From 351990b95e82cf7c4f430157a277030fc1f53be4 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Mon, 21 Nov 2022 15:25:59 -0800 Subject: [PATCH] Stick to idiomatic naming conventions --- src/parse/address.rs | 66 ++++++++++++++++----------------- src/parse/command.rs | 62 +++++++++++++++---------------- src/parse/mod.rs | 32 ++++++++-------- src/parse/response.rs | 70 +++++++++++++++++------------------ src/types.rs | 86 +++++++++++++++++++++---------------------- 5 files changed, 157 insertions(+), 159 deletions(-) diff --git a/src/parse/address.rs b/src/parse/address.rs index 9c2a8c9..7e2584c 100644 --- a/src/parse/address.rs +++ b/src/parse/address.rs @@ -10,7 +10,7 @@ use nom::{ IResult, }; -use crate::parse::Ldh_str; +use crate::parse::ldh_str; /// address-literal = "[" ( /// IPv4-address-literal / @@ -23,9 +23,9 @@ pub fn address_literal(input: &[u8]) -> IResult<&[u8], &str> { tag(b"["), map_res( alt(( - IPv4_address_literal, - IPv6_address_literal, - General_address_literal, + ipv4_address_literal, + ipv6_address_literal, + general_address_literal, )), std::str::from_utf8, ), @@ -34,8 +34,8 @@ pub fn address_literal(input: &[u8]) -> IResult<&[u8], &str> { } /// IPv4-address-literal = Snum 3("." Snum) -pub fn IPv4_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((Snum, count(tuple((tag(b"."), Snum)), 3))); +pub fn ipv4_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { + let parser = tuple((snum, count(tuple((tag(b"."), snum)), 3))); let (remaining, parsed) = recognize(parser)(input)?; @@ -45,13 +45,13 @@ pub fn IPv4_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { /// Representing a decimal integer value in the range 0 through 255 /// /// Snum = 1*3DIGIT -pub fn Snum(input: &[u8]) -> IResult<&[u8], &[u8]> { +pub fn snum(input: &[u8]) -> IResult<&[u8], &[u8]> { take_while_m_n(1, 3, is_digit)(input) } /// IPv6-address-literal = "IPv6:" IPv6-addr -pub fn IPv6_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((tag_no_case(b"IPv6:"), IPv6_addr)); +pub fn ipv6_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { + let parser = tuple((tag_no_case(b"IPv6:"), ipv6_addr)); let (remaining, parsed) = recognize(parser)(input)?; @@ -59,8 +59,8 @@ pub fn IPv6_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { } /// IPv6-addr = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp -pub fn IPv6_addr(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = alt((IPv6_full, IPv6_comp, IPv6v4_full, IPv6v4_comp)); +pub fn ipv6_addr(input: &[u8]) -> IResult<&[u8], &[u8]> { + let parser = alt((ipv6_full, ipv6_comp, ipv6v4_full, ipv6v4_comp)); let (remaining, parsed) = recognize(parser)(input)?; @@ -68,8 +68,8 @@ pub fn IPv6_addr(input: &[u8]) -> IResult<&[u8], &[u8]> { } /// IPv6-full = IPv6-hex 7(":" IPv6-hex) -pub fn IPv6_full(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((IPv6_hex, count(tuple((tag(b":"), IPv6_hex)), 7))); +pub fn ipv6_full(input: &[u8]) -> IResult<&[u8], &[u8]> { + let parser = tuple((ipv6_hex, count(tuple((tag(b":"), ipv6_hex)), 7))); let (remaining, parsed) = recognize(parser)(input)?; @@ -77,7 +77,7 @@ pub fn IPv6_full(input: &[u8]) -> IResult<&[u8], &[u8]> { } /// IPv6-hex = 1*4HEXDIG -pub fn IPv6_hex(input: &[u8]) -> IResult<&[u8], &[u8]> { +pub fn ipv6_hex(input: &[u8]) -> IResult<&[u8], &[u8]> { take_while_m_n(1, 4, is_hex_digit)(input) } @@ -85,16 +85,16 @@ pub fn IPv6_hex(input: &[u8]) -> IResult<&[u8], &[u8]> { /// No more than 6 groups in addition to the "::" may be present. /// /// IPv6-comp = [IPv6-hex *5(":" IPv6-hex)] "::" [IPv6-hex *5(":" IPv6-hex)] -pub fn IPv6_comp(input: &[u8]) -> IResult<&[u8], &[u8]> { +pub fn ipv6_comp(input: &[u8]) -> IResult<&[u8], &[u8]> { let parser = tuple(( opt(tuple(( - IPv6_hex, - many_m_n(0, 5, tuple((tag(b":"), IPv6_hex))), + ipv6_hex, + many_m_n(0, 5, tuple((tag(b":"), ipv6_hex))), ))), tag(b"::"), opt(tuple(( - IPv6_hex, - many_m_n(0, 5, tuple((tag(b":"), IPv6_hex))), + ipv6_hex, + many_m_n(0, 5, tuple((tag(b":"), ipv6_hex))), ))), )); @@ -104,12 +104,12 @@ pub fn IPv6_comp(input: &[u8]) -> IResult<&[u8], &[u8]> { } /// IPv6v4-full = IPv6-hex 5(":" IPv6-hex) ":" IPv4-address-literal -pub fn IPv6v4_full(input: &[u8]) -> IResult<&[u8], &[u8]> { +pub fn ipv6v4_full(input: &[u8]) -> IResult<&[u8], &[u8]> { let parser = tuple(( - IPv6_hex, - count(tuple((tag(b":"), IPv6_hex)), 5), + ipv6_hex, + count(tuple((tag(b":"), ipv6_hex)), 5), tag(b":"), - IPv4_address_literal, + ipv4_address_literal, )); let (remaining, parsed) = recognize(parser)(input)?; @@ -123,19 +123,19 @@ pub fn IPv6v4_full(input: &[u8]) -> IResult<&[u8], &[u8]> { /// IPv6v4-comp = [IPv6-hex *3(":" IPv6-hex)] "::" /// [IPv6-hex *3(":" IPv6-hex) ":"] /// IPv4-address-literal -pub fn IPv6v4_comp(input: &[u8]) -> IResult<&[u8], &[u8]> { +pub fn ipv6v4_comp(input: &[u8]) -> IResult<&[u8], &[u8]> { let parser = tuple(( opt(tuple(( - IPv6_hex, - many_m_n(0, 3, tuple((tag(b":"), IPv6_hex))), + ipv6_hex, + many_m_n(0, 3, tuple((tag(b":"), ipv6_hex))), ))), tag(b"::"), opt(tuple(( - IPv6_hex, - many_m_n(0, 3, tuple((tag(b":"), IPv6_hex))), + ipv6_hex, + many_m_n(0, 3, tuple((tag(b":"), ipv6_hex))), tag(b":"), ))), - IPv4_address_literal, + ipv4_address_literal, )); let (remaining, parsed) = recognize(parser)(input)?; @@ -144,8 +144,8 @@ pub fn IPv6v4_comp(input: &[u8]) -> IResult<&[u8], &[u8]> { } /// General-address-literal = Standardized-tag ":" 1*dcontent -pub fn General_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((Standardized_tag, tag(b":"), take_while1(is_dcontent))); +pub fn general_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { + let parser = tuple((standardized_tag, tag(b":"), take_while1(is_dcontent))); let (remaining, parsed) = recognize(parser)(input)?; @@ -155,8 +155,8 @@ pub fn General_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { /// Standardized-tag MUST be specified in a Standards-Track RFC and registered with IANA /// /// Standardized-tag = Ldh-str -pub fn Standardized_tag(input: &[u8]) -> IResult<&[u8], &[u8]> { - Ldh_str(input) +pub fn standardized_tag(input: &[u8]) -> IResult<&[u8], &[u8]> { + ldh_str(input) } /// Printable US-ASCII excl. "[", "\", "]" diff --git a/src/parse/command.rs b/src/parse/command.rs index be8d953..4d74089 100644 --- a/src/parse/command.rs +++ b/src/parse/command.rs @@ -9,7 +9,7 @@ use nom::{ }; use crate::{ - parse::{address::address_literal, base64, Atom, Domain, Quoted_string, String}, + parse::{address::address_literal, atom, base64, domain, quoted_string, string}, types::{Command, DomainOrAddress, Parameter}, }; @@ -28,7 +28,7 @@ pub fn helo(input: &[u8]) -> IResult<&[u8], Command> { tag_no_case(b"HELO"), tag(" "), alt(( - map(Domain, |domain| DomainOrAddress::Domain(domain.into())), + map(domain, |domain| DomainOrAddress::Domain(domain.into())), map(address_literal, |address| { DomainOrAddress::Address(address.into()) }), @@ -47,7 +47,7 @@ pub fn ehlo(input: &[u8]) -> IResult<&[u8], Command> { tag_no_case(b"EHLO"), tag(" "), alt(( - map(Domain, |domain| DomainOrAddress::Domain(domain.into())), + map(domain, |domain| DomainOrAddress::Domain(domain.into())), map(address_literal, |address| { DomainOrAddress::Address(address.into()) }), @@ -65,8 +65,8 @@ pub fn mail(input: &[u8]) -> IResult<&[u8], Command> { let mut parser = tuple(( tag_no_case(b"MAIL FROM:"), opt(tag(" ")), // Out-of-tag(" ")ec, but Outlook does it ... - Reverse_path, - opt(preceded(tag(" "), Mail_parameters)), + reverse_path, + opt(preceded(tag(" "), mail_parameters)), tag("\r\n"), )); @@ -82,7 +82,7 @@ pub fn mail(input: &[u8]) -> IResult<&[u8], Command> { } /// Mail-parameters = esmtp-param *(tag(" ") esmtp-param) -pub fn Mail_parameters(input: &[u8]) -> IResult<&[u8], Vec> { +pub fn mail_parameters(input: &[u8]) -> IResult<&[u8], Vec> { separated_list1(tag(" "), esmtp_param)(input) } @@ -138,13 +138,13 @@ pub fn rcpt(input: &[u8]) -> IResult<&[u8], Command> { opt(tag(" ")), // Out-of-tag(" ")ec, but Outlook does it ... alt(( map_res( - recognize(tuple((tag_no_case("")))), + recognize(tuple((tag_no_case("")))), std::str::from_utf8, ), map_res(tag_no_case(""), std::str::from_utf8), - Forward_path, + forward_path, )), - opt(preceded(tag(" "), Rcpt_parameters)), + opt(preceded(tag(" "), rcpt_parameters)), tag("\r\n"), )); @@ -160,7 +160,7 @@ pub fn rcpt(input: &[u8]) -> IResult<&[u8], Command> { } /// Rcpt-parameters = esmtp-param *(tag(" ") esmtp-param) -pub fn Rcpt_parameters(input: &[u8]) -> IResult<&[u8], Vec> { +pub fn rcpt_parameters(input: &[u8]) -> IResult<&[u8], Vec> { separated_list1(tag(" "), esmtp_param)(input) } @@ -176,7 +176,7 @@ pub fn rset(input: &[u8]) -> IResult<&[u8], Command> { /// vrfy = "VRFY" tag(" ") String CRLF pub fn vrfy(input: &[u8]) -> IResult<&[u8], Command> { - let mut parser = tuple((tag_no_case(b"VRFY"), tag(" "), String, tag("\r\n"))); + let mut parser = tuple((tag_no_case(b"VRFY"), tag(" "), string, tag("\r\n"))); let (remaining, (_, _, data, _)) = parser(input)?; @@ -190,7 +190,7 @@ pub fn vrfy(input: &[u8]) -> IResult<&[u8], Command> { /// expn = "EXPN" tag(" ") String CRLF pub fn expn(input: &[u8]) -> IResult<&[u8], Command> { - let mut parser = tuple((tag_no_case(b"EXPN"), tag(" "), String, tag("\r\n"))); + let mut parser = tuple((tag_no_case(b"EXPN"), tag(" "), string, tag("\r\n"))); let (remaining, (_, _, data, _)) = parser(input)?; @@ -201,7 +201,7 @@ pub fn expn(input: &[u8]) -> IResult<&[u8], Command> { pub fn help(input: &[u8]) -> IResult<&[u8], Command> { let mut parser = tuple(( tag_no_case(b"HELP"), - opt(preceded(tag(" "), String)), + opt(preceded(tag(" "), string)), tag("\r\n"), )); @@ -219,7 +219,7 @@ pub fn help(input: &[u8]) -> IResult<&[u8], Command> { pub fn noop(input: &[u8]) -> IResult<&[u8], Command> { let mut parser = tuple(( tag_no_case(b"NOOP"), - opt(preceded(tag(" "), String)), + opt(preceded(tag(" "), string)), tag("\r\n"), )); @@ -240,7 +240,7 @@ pub fn quit(input: &[u8]) -> IResult<&[u8], Command> { pub fn starttls(input: &[u8]) -> IResult<&[u8], Command> { value( - Command::StartTLS, + Command::StartTls, tuple((tag_no_case(b"STARTTLS"), tag("\r\n"))), )(input) } @@ -293,21 +293,21 @@ pub fn auth_plain(input: &[u8]) -> IResult<&[u8], Command> { // ----- 4.1.2. Command Argument Syntax (RFC 5321) ----- /// Reverse-path = Path / "<>" -pub fn Reverse_path(input: &[u8]) -> IResult<&[u8], &str> { - alt((Path, value("", tag("<>"))))(input) +pub fn reverse_path(input: &[u8]) -> IResult<&[u8], &str> { + alt((path, value("", tag("<>"))))(input) } /// Forward-path = Path -pub fn Forward_path(input: &[u8]) -> IResult<&[u8], &str> { - Path(input) +pub fn forward_path(input: &[u8]) -> IResult<&[u8], &str> { + path(input) } // Path = "<" [ A-d-l ":" ] Mailbox ">" -pub fn Path(input: &[u8]) -> IResult<&[u8], &str> { +pub fn path(input: &[u8]) -> IResult<&[u8], &str> { delimited( tag(b"<"), map_res( - recognize(tuple((opt(tuple((A_d_l, tag(b":")))), Mailbox))), + recognize(tuple((opt(tuple((a_d_l, tag(b":")))), mailbox))), std::str::from_utf8, ), tag(b">"), @@ -318,8 +318,8 @@ pub fn Path(input: &[u8]) -> IResult<&[u8], &str> { /// ; Note that this form, the so-called "source /// ; route", MUST BE accepted, SHOULD NOT be /// ; generated, and SHOULD be ignored. -pub fn A_d_l(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = separated_list1(tag(b","), At_domain); +pub fn a_d_l(input: &[u8]) -> IResult<&[u8], &[u8]> { + let parser = separated_list1(tag(b","), at_domain); let (remaining, parsed) = recognize(parser)(input)?; @@ -327,8 +327,8 @@ pub fn A_d_l(input: &[u8]) -> IResult<&[u8], &[u8]> { } /// At-domain = "@" Domain -pub fn At_domain(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((tag(b"@"), Domain)); +pub fn at_domain(input: &[u8]) -> IResult<&[u8], &[u8]> { + let parser = tuple((tag(b"@"), domain)); let (remaining, parsed) = recognize(parser)(input)?; @@ -336,8 +336,8 @@ pub fn At_domain(input: &[u8]) -> IResult<&[u8], &[u8]> { } /// Mailbox = Local-part "@" ( Domain / address-literal ) -pub fn Mailbox(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((Local_part, tag(b"@"), alt((Domain, address_literal)))); +pub fn mailbox(input: &[u8]) -> IResult<&[u8], &[u8]> { + let parser = tuple((local_part, tag(b"@"), alt((domain, address_literal)))); let (remaining, parsed) = recognize(parser)(input)?; @@ -346,14 +346,14 @@ pub fn Mailbox(input: &[u8]) -> IResult<&[u8], &[u8]> { /// Local-part = Dot-string / Quoted-string /// ; MAY be case-sensitive -pub fn Local_part(input: &[u8]) -> IResult<&[u8], &[u8]> { - alt((recognize(Dot_string), recognize(Quoted_string)))(input) +pub fn local_part(input: &[u8]) -> IResult<&[u8], &[u8]> { + alt((recognize(dot_string), recognize(quoted_string)))(input) } /// Dot-string = Atom *("." Atom) -pub fn Dot_string(input: &[u8]) -> IResult<&[u8], &str> { +pub fn dot_string(input: &[u8]) -> IResult<&[u8], &str> { map_res( - recognize(separated_list1(tag(b"."), Atom)), + recognize(separated_list1(tag(b"."), atom)), std::str::from_utf8, )(input) } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 4ad6963..905c03f 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -1,5 +1,3 @@ -#![allow(non_snake_case)] - use std::{borrow::Cow, str::from_utf8}; use nom::{ @@ -44,15 +42,15 @@ pub fn number(input: &[u8]) -> IResult<&[u8], u32> { // ------------------------------------------------------------------------------------------------- /// String = Atom / Quoted-string -pub fn String(input: &[u8]) -> IResult<&[u8], AtomOrQuoted> { +pub fn string(input: &[u8]) -> IResult<&[u8], AtomOrQuoted> { alt(( - map(Atom, |atom| AtomOrQuoted::Atom(atom.into())), - map(Quoted_string, |quoted| AtomOrQuoted::Quoted(quoted.into())), + map(atom, |atom| AtomOrQuoted::Atom(atom.into())), + map(quoted_string, |quoted| AtomOrQuoted::Quoted(quoted.into())), ))(input) } /// Atom = 1*atext -pub fn Atom(input: &[u8]) -> IResult<&[u8], &str> { +pub fn atom(input: &[u8]) -> IResult<&[u8], &str> { map_res(take_while1(is_atext), std::str::from_utf8)(input) } @@ -77,11 +75,11 @@ pub fn is_atext(byte: u8) -> bool { } /// Quoted-string = DQUOTE *QcontentSMTP DQUOTE -pub fn Quoted_string(input: &[u8]) -> IResult<&[u8], Cow<'_, str>> { +pub fn quoted_string(input: &[u8]) -> IResult<&[u8], Cow<'_, str>> { map( delimited( tag("\""), - map_res(recognize(many0(QcontentSMTP)), std::str::from_utf8), + map_res(recognize(many0(q_content_smtp)), std::str::from_utf8), tag("\""), ), unescape_quoted, @@ -89,8 +87,8 @@ pub fn Quoted_string(input: &[u8]) -> IResult<&[u8], Cow<'_, str>> { } /// QcontentSMTP = qtextSMTP / quoted-pairSMTP -pub fn QcontentSMTP(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = alt((take_while_m_n(1, 1, is_qtextSMTP), quoted_pairSMTP)); +pub fn q_content_smtp(input: &[u8]) -> IResult<&[u8], &[u8]> { + let parser = alt((take_while_m_n(1, 1, is_qtext_smtp), quoted_pair_smtp)); let (remaining, parsed) = recognize(parser)(input)?; @@ -101,7 +99,7 @@ pub fn QcontentSMTP(input: &[u8]) -> IResult<&[u8], &[u8]> { /// without blackslash-quoting except double-quote and the backslash itself. /// /// qtextSMTP = %d32-33 / %d35-91 / %d93-126 -pub fn is_qtextSMTP(byte: u8) -> bool { +pub fn is_qtext_smtp(byte: u8) -> bool { matches!(byte, 32..=33 | 35..=91 | 93..=126) } @@ -110,7 +108,7 @@ pub fn is_qtextSMTP(byte: u8) -> bool { /// quoted-pairSMTP = %d92 %d32-126 /// /// FIXME: How should e.g. "\a" be interpreted? -pub fn quoted_pairSMTP(input: &[u8]) -> IResult<&[u8], &[u8]> { +pub fn quoted_pair_smtp(input: &[u8]) -> IResult<&[u8], &[u8]> { //fn is_value(byte: u8) -> bool { // matches!(byte, 32..=126) //} @@ -130,7 +128,7 @@ pub fn quoted_pairSMTP(input: &[u8]) -> IResult<&[u8], &[u8]> { // ------------------------------------------------------------------------------------------------- /// Domain = sub-domain *("." sub-domain) -pub fn Domain(input: &[u8]) -> IResult<&[u8], &str> { +pub fn domain(input: &[u8]) -> IResult<&[u8], &str> { let parser = separated_list1(tag(b"."), sub_domain); let (remaining, parsed) = map_res(recognize(parser), std::str::from_utf8)(input)?; @@ -140,7 +138,7 @@ pub fn Domain(input: &[u8]) -> IResult<&[u8], &str> { /// sub-domain = Let-dig [Ldh-str] pub fn sub_domain(input: &[u8]) -> IResult<&[u8], &[u8]> { - let parser = tuple((take_while_m_n(1, 1, is_Let_dig), opt(Ldh_str))); + let parser = tuple((take_while_m_n(1, 1, is_let_dig), opt(ldh_str))); let (remaining, parsed) = recognize(parser)(input)?; @@ -148,16 +146,16 @@ pub fn sub_domain(input: &[u8]) -> IResult<&[u8], &[u8]> { } /// Let-dig = ALPHA / DIGIT -pub fn is_Let_dig(byte: u8) -> bool { +pub fn is_let_dig(byte: u8) -> bool { is_alphabetic(byte) || is_digit(byte) } /// Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig -pub fn Ldh_str(input: &[u8]) -> IResult<&[u8], &[u8]> { +pub fn ldh_str(input: &[u8]) -> IResult<&[u8], &[u8]> { let parser = many0(alt(( take_while_m_n(1, 1, is_alphabetic), take_while_m_n(1, 1, is_digit), - recognize(tuple((tag(b"-"), take_while_m_n(1, 1, is_Let_dig)))), + recognize(tuple((tag(b"-"), take_while_m_n(1, 1, is_let_dig)))), ))); let (remaining, parsed) = recognize(parser)(input)?; diff --git a/src/parse/response.rs b/src/parse/response.rs index 62cd8a5..1845cad 100644 --- a/src/parse/response.rs +++ b/src/parse/response.rs @@ -11,7 +11,7 @@ use nom::{ }; use crate::{ - parse::{address::address_literal, number, Domain}, + parse::{address::address_literal, domain, number}, types::{AuthMechanism, Capability, ReplyCode, Response, TextString}, }; @@ -19,12 +19,12 @@ use crate::{ /// ( "220-" (Domain / address-literal) [ SP textstring ] CRLF /// *( "220-" [ textstring ] CRLF ) /// "220" [ SP textstring ] CRLF ) -pub fn Greeting(input: &[u8]) -> IResult<&[u8], Response> { +pub fn greeting(input: &[u8]) -> IResult<&[u8], Response> { let mut parser = alt(( map( tuple(( tag(b"220 "), - alt((Domain, address_literal)), + alt((domain, address_literal)), opt(preceded(tag(" "), textstring)), tag("\r\n"), )), @@ -38,7 +38,7 @@ pub fn Greeting(input: &[u8]) -> IResult<&[u8], Response> { map( tuple(( tag(b"220-"), - alt((Domain, address_literal)), + alt((domain, address_literal)), opt(preceded(tag(" "), textstring)), tag("\r\n"), many0(delimited(tag(b"220-"), opt(textstring), tag("\r\n"))), @@ -94,11 +94,11 @@ pub(crate) fn is_text_string_byte(byte: u8) -> bool { /// Reply-line = *( Reply-code "-" [ textstring ] CRLF ) /// Reply-code [ SP textstring ] CRLF -pub fn Reply_lines(input: &[u8]) -> IResult<&[u8], Response> { +pub fn reply_lines(input: &[u8]) -> IResult<&[u8], Response> { let mut parser = map( tuple(( - many0(tuple((Reply_code, tag(b"-"), opt(textstring), tag("\r\n")))), - Reply_code, + many0(tuple((reply_code, tag(b"-"), opt(textstring), tag("\r\n")))), + reply_code, opt(tuple((tag(" "), textstring))), tag("\r\n"), )), @@ -129,7 +129,7 @@ pub fn Reply_lines(input: &[u8]) -> IResult<&[u8], Response> { /// 2345 /// 012345 /// 0123456789 -pub fn Reply_code(input: &[u8]) -> IResult<&[u8], ReplyCode> { +pub fn reply_code(input: &[u8]) -> IResult<&[u8], ReplyCode> { // FIXME: do not accept all codes. map_res( map_res( @@ -153,7 +153,7 @@ pub fn ehlo_ok_rsp(input: &[u8]) -> IResult<&[u8], Response> { map( tuple(( tag(b"250 "), - Domain, + domain, opt(preceded(tag(" "), ehlo_greet)), tag("\r\n"), )), @@ -166,7 +166,7 @@ pub fn ehlo_ok_rsp(input: &[u8]) -> IResult<&[u8], Response> { map( tuple(( tag(b"250-"), - Domain, + domain, opt(preceded(tag(" "), ehlo_greet)), tag("\r\n"), many0(delimited(tag(b"250-"), ehlo_line, tag("\r\n"))), @@ -220,34 +220,34 @@ pub fn ehlo_line(input: &[u8]) -> IResult<&[u8], Capability> { )); alt(( - value(Capability::EXPN, tag_no_case("EXPN")), + value(Capability::Expn, tag_no_case("EXPN")), value(Capability::Help, tag_no_case("HELP")), - value(Capability::EightBitMIME, tag_no_case("8BITMIME")), + value(Capability::EightBitMime, tag_no_case("8BITMIME")), map(preceded(tag_no_case("SIZE "), number), Capability::Size), value(Capability::Chunking, tag_no_case("CHUNKING")), - value(Capability::BinaryMIME, tag_no_case("BINARYMIME")), + value(Capability::BinaryMime, tag_no_case("BINARYMIME")), value(Capability::Checkpoint, tag_no_case("CHECKPOINT")), value(Capability::DeliverBy, tag_no_case("DELIVERBY")), value(Capability::Pipelining, tag_no_case("PIPELINING")), - value(Capability::DSN, tag_no_case("DSN")), - value(Capability::ETRN, tag_no_case("ETRN")), + value(Capability::Dsn, tag_no_case("DSN")), + value(Capability::Etrn, tag_no_case("ETRN")), value( Capability::EnhancedStatusCodes, tag_no_case("ENHANCEDSTATUSCODES"), ), - value(Capability::StartTLS, tag_no_case("STARTTLS")), + value(Capability::StartTls, tag_no_case("STARTTLS")), // FIXME: NO-SOLICITING - value(Capability::MTRK, tag_no_case("MTRK")), - value(Capability::ATRN, tag_no_case("ATRN")), + value(Capability::Mtrk, tag_no_case("MTRK")), + value(Capability::Atrn, tag_no_case("ATRN")), map(auth, |(_, _, mechanisms)| Capability::Auth(mechanisms)), - value(Capability::BURL, tag_no_case("BURL")), + value(Capability::Burl, tag_no_case("BURL")), // FIXME: FUTURERELEASE // FIXME: CONPERM // FIXME: CONNEG - value(Capability::SMTPUTF8, tag_no_case("SMTPUTF8")), + value(Capability::SmtpUtf8, tag_no_case("SMTPUTF8")), // FIXME: MT-PRIORITY - value(Capability::RRVS, tag_no_case("RRVS")), - value(Capability::RequireTLS, tag_no_case("REQUIRETLS")), + value(Capability::Rrvs, tag_no_case("RRVS")), + value(Capability::RequireTls, tag_no_case("REQUIRETLS")), map(other, |(keyword, params)| Capability::Other { keyword: keyword.into(), params: params @@ -287,12 +287,12 @@ pub fn auth_mechanism(input: &[u8]) -> IResult<&[u8], AuthMechanism> { alt(( value(AuthMechanism::Login, tag_no_case("LOGIN")), value(AuthMechanism::Plain, tag_no_case("PLAIN")), - value(AuthMechanism::CramMD5, tag_no_case("CRAM-MD5")), - value(AuthMechanism::CramSHA1, tag_no_case("CRAM-SHA1")), - value(AuthMechanism::DigestMD5, tag_no_case("DIGEST-MD5")), - value(AuthMechanism::ScramMD5, tag_no_case("SCRAM-MD5")), - value(AuthMechanism::GSSAPI, tag_no_case("GSSAPI")), - value(AuthMechanism::NTLM, tag_no_case("NTLM")), + value(AuthMechanism::CramMd5, tag_no_case("CRAM-MD5")), + value(AuthMechanism::CramSha1, tag_no_case("CRAM-SHA1")), + value(AuthMechanism::DigestMd5, tag_no_case("DIGEST-MD5")), + value(AuthMechanism::ScramMd5, tag_no_case("SCRAM-MD5")), + value(AuthMechanism::GssApi, tag_no_case("GSSAPI")), + value(AuthMechanism::Ntlm, tag_no_case("NTLM")), map(ehlo_param, |param| AuthMechanism::Other(param.to_string())), ))(input) } @@ -305,12 +305,12 @@ mod test { use crate::types::AuthMechanism; #[test] - fn test_Greeting() { - let greeting = b"220-example.org ESMTP Fake 4.93 #2 Thu, 16 Jul 2020 07:30:16 -0400\r\n\ + fn test_greeting() { + let buf = b"220-example.org ESMTP Fake 4.93 #2 Thu, 16 Jul 2020 07:30:16 -0400\r\n\ 220-We do not authorize the use of this system to transport unsolicited,\r\n\ 220 and/or bulk e-mail.\r\n"; - let (rem, out) = Greeting(greeting).unwrap(); + let (rem, out) = greeting(buf).unwrap(); assert_eq!(rem, b""); assert_eq!( out, @@ -344,17 +344,17 @@ and/or bulk e-mail." capabilities: vec![ Capability::Auth(vec![ AuthMechanism::Login, - AuthMechanism::CramMD5, + AuthMechanism::CramMd5, AuthMechanism::Plain ]), Capability::Auth(vec![ AuthMechanism::Login, - AuthMechanism::CramMD5, + AuthMechanism::CramMd5, AuthMechanism::Plain ]), - Capability::StartTLS, + Capability::StartTls, Capability::Size(12345), - Capability::EightBitMIME, + Capability::EightBitMime, ], } ); diff --git a/src/types.rs b/src/types.rs index ff8658b..50783c3 100644 --- a/src/types.rs +++ b/src/types.rs @@ -89,7 +89,7 @@ pub enum Command { /// mail transaction will be aborted. Quit, // Extensions - StartTLS, + StartTls, // AUTH LOGIN AuthLogin(Option), // AUTH PLAIN @@ -149,7 +149,7 @@ impl Command { Command::Noop { .. } => "NOOP", Command::Quit => "QUIT", // Extensions - Command::StartTLS => "STARTTLS", + Command::StartTls => "STARTTLS", // TODO: SMTP AUTH LOGIN Command::AuthLogin(_) => "AUTHLOGIN", // TODO: SMTP AUTH PLAIN @@ -233,7 +233,7 @@ impl Command { Quit => writer.write_all(b"QUIT")?, // ----- Extensions ----- // starttls = "STARTTLS" CRLF - StartTLS => writer.write_all(b"STARTTLS")?, + StartTls => writer.write_all(b"STARTTLS")?, // auth_login_command = "AUTH LOGIN" [SP username] CRLF AuthLogin(None) => { writer.write_all(b"AUTH LOGIN")?; @@ -316,7 +316,7 @@ pub enum Response { impl Response { pub fn parse_greeting(input: &[u8]) -> IResult<&[u8], Self> { - crate::parse::response::Greeting(input) + crate::parse::response::greeting(input) } pub fn greeting(domain: D, text: T) -> Response @@ -335,7 +335,7 @@ impl Response { } pub fn parse_other(input: &[u8]) -> IResult<&[u8], Self> { - crate::parse::response::Reply_lines(input) + crate::parse::response::reply_lines(input) } pub fn ehlo(domain: D, greet: Option, capabilities: Vec) -> Response @@ -465,13 +465,13 @@ pub enum Capability { /// Expand the mailing list [RFC821] /// Command description updated by [RFC5321] - EXPN, + Expn, /// Supply helpful information [RFC821] /// Command description updated by [RFC5321] Help, /// SMTP and Submit transport of 8bit MIME content [RFC6152] - EightBitMIME, + EightBitMime, /// Message size declaration [RFC1870] Size(u32), @@ -480,7 +480,7 @@ pub enum Capability { Chunking, /// Binary MIME [RFC3030] - BinaryMIME, + BinaryMime, /// Checkpoint/Restart [RFC1845] Checkpoint, @@ -492,34 +492,34 @@ pub enum Capability { Pipelining, /// Delivery Status Notification [RFC3461] - DSN, + Dsn, /// Extended Turn [RFC1985] /// SMTP [RFC5321] only. Not for use on Submit port 587. - ETRN, + Etrn, /// Enhanced Status Codes [RFC2034] EnhancedStatusCodes, /// Start TLS [RFC3207] - StartTLS, + StartTls, /// Notification of no soliciting [RFC3865] // NoSoliciting, /// Message Tracking [RFC3885] - MTRK, + Mtrk, /// Authenticated TURN [RFC2645] /// SMTP [RFC5321] only. Not for use on Submit port 587. - ATRN, + Atrn, /// Authentication [RFC4954] Auth(Vec), /// Remote Content [RFC4468] /// Submit [RFC6409] only. Not for use with SMTP on port 25. - BURL, + Burl, /// Future Message Release [RFC4865] // FutureRelease, @@ -531,16 +531,16 @@ pub enum Capability { // ConNeg, /// Internationalized email address [RFC6531] - SMTPUTF8, + SmtpUtf8, /// Priority Message Handling [RFC6710] // MTPRIORITY, /// Require Recipient Valid Since [RFC7293] - RRVS, + Rrvs, /// Require TLS [RFC8689] - RequireTLS, + RequireTls, // Observed ... // TIME, @@ -557,21 +557,21 @@ pub enum Capability { impl Capability { pub fn serialize(&self, writer: &mut impl Write) -> std::io::Result<()> { match self { - Capability::EXPN => writer.write_all(b"EXPN"), + Capability::Expn => writer.write_all(b"EXPN"), Capability::Help => writer.write_all(b"HELP"), - Capability::EightBitMIME => writer.write_all(b"8BITMIME"), + Capability::EightBitMime => writer.write_all(b"8BITMIME"), Capability::Size(number) => writer.write_all(format!("SIZE {}", number).as_bytes()), Capability::Chunking => writer.write_all(b"CHUNKING"), - Capability::BinaryMIME => writer.write_all(b"BINARYMIME"), + Capability::BinaryMime => writer.write_all(b"BINARYMIME"), Capability::Checkpoint => writer.write_all(b"CHECKPOINT"), Capability::DeliverBy => writer.write_all(b"DELIVERBY"), Capability::Pipelining => writer.write_all(b"PIPELINING"), - Capability::DSN => writer.write_all(b"DSN"), - Capability::ETRN => writer.write_all(b"ETRN"), + Capability::Dsn => writer.write_all(b"DSN"), + Capability::Etrn => writer.write_all(b"ETRN"), Capability::EnhancedStatusCodes => writer.write_all(b"ENHANCEDSTATUSCODES"), - Capability::StartTLS => writer.write_all(b"STARTTLS"), - Capability::MTRK => writer.write_all(b"MTRK"), - Capability::ATRN => writer.write_all(b"ATRN"), + Capability::StartTls => writer.write_all(b"STARTTLS"), + Capability::Mtrk => writer.write_all(b"MTRK"), + Capability::Atrn => writer.write_all(b"ATRN"), Capability::Auth(mechanisms) => { if let Some((tail, head)) = mechanisms.split_last() { writer.write_all(b"AUTH ")?; @@ -586,10 +586,10 @@ impl Capability { writer.write_all(b"AUTH") } } - Capability::BURL => writer.write_all(b"BURL"), - Capability::SMTPUTF8 => writer.write_all(b"SMTPUTF8"), - Capability::RRVS => writer.write_all(b"RRVS"), - Capability::RequireTLS => writer.write_all(b"REQUIRETLS"), + Capability::Burl => writer.write_all(b"BURL"), + Capability::SmtpUtf8 => writer.write_all(b"SMTPUTF8"), + Capability::Rrvs => writer.write_all(b"RRVS"), + Capability::RequireTls => writer.write_all(b"REQUIRETLS"), Capability::Other { keyword, params } => { if let Some((tail, head)) = params.split_last() { writer.write_all(keyword.as_bytes())?; @@ -773,13 +773,13 @@ impl From for u16 { pub enum AuthMechanism { Plain, Login, - GSSAPI, + GssApi, - CramMD5, - CramSHA1, - ScramMD5, - DigestMD5, - NTLM, + CramMd5, + CramSha1, + ScramMd5, + DigestMd5, + Ntlm, Other(String), } @@ -789,13 +789,13 @@ impl AuthMechanism { match self { AuthMechanism::Plain => writer.write_all(b"PLAIN"), AuthMechanism::Login => writer.write_all(b"LOGIN"), - AuthMechanism::GSSAPI => writer.write_all(b"GSSAPI"), + AuthMechanism::GssApi => writer.write_all(b"GSSAPI"), - AuthMechanism::CramMD5 => writer.write_all(b"CRAM-MD5"), - AuthMechanism::CramSHA1 => writer.write_all(b"CRAM-SHA1"), - AuthMechanism::ScramMD5 => writer.write_all(b"SCRAM-MD5"), - AuthMechanism::DigestMD5 => writer.write_all(b"DIGEST-MD5"), - AuthMechanism::NTLM => writer.write_all(b"NTLM"), + AuthMechanism::CramMd5 => writer.write_all(b"CRAM-MD5"), + AuthMechanism::CramSha1 => writer.write_all(b"CRAM-SHA1"), + AuthMechanism::ScramMd5 => writer.write_all(b"SCRAM-MD5"), + AuthMechanism::DigestMd5 => writer.write_all(b"DIGEST-MD5"), + AuthMechanism::Ntlm => writer.write_all(b"NTLM"), AuthMechanism::Other(other) => writer.write_all(other.as_bytes()), } @@ -912,7 +912,7 @@ mod tests { Response::Ehlo { domain: "example.org".into(), greet: Some("...".into()), - capabilities: vec![Capability::StartTLS], + capabilities: vec![Capability::StartTls], }, b"250-example.org ...\r\n250 STARTTLS\r\n".as_ref(), ), @@ -920,7 +920,7 @@ mod tests { Response::Ehlo { domain: "example.org".into(), greet: Some("...".into()), - capabilities: vec![Capability::StartTLS, Capability::Size(12345)], + capabilities: vec![Capability::StartTls, Capability::Size(12345)], }, b"250-example.org ...\r\n250-STARTTLS\r\n250 SIZE 12345\r\n".as_ref(), ),