Stick to idiomatic naming conventions

This commit is contained in:
Dirkjan Ochtman 2022-11-21 15:25:59 -08:00
parent 263c2c16cd
commit 351990b95e
5 changed files with 157 additions and 159 deletions

View File

@ -10,7 +10,7 @@ use nom::{
IResult, IResult,
}; };
use crate::parse::Ldh_str; use crate::parse::ldh_str;
/// address-literal = "[" ( /// address-literal = "[" (
/// IPv4-address-literal / /// IPv4-address-literal /
@ -23,9 +23,9 @@ pub fn address_literal(input: &[u8]) -> IResult<&[u8], &str> {
tag(b"["), tag(b"["),
map_res( map_res(
alt(( alt((
IPv4_address_literal, ipv4_address_literal,
IPv6_address_literal, ipv6_address_literal,
General_address_literal, general_address_literal,
)), )),
std::str::from_utf8, std::str::from_utf8,
), ),
@ -34,8 +34,8 @@ pub fn address_literal(input: &[u8]) -> IResult<&[u8], &str> {
} }
/// IPv4-address-literal = Snum 3("." Snum) /// IPv4-address-literal = Snum 3("." Snum)
pub fn IPv4_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn ipv4_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((Snum, count(tuple((tag(b"."), Snum)), 3))); let parser = tuple((snum, count(tuple((tag(b"."), snum)), 3)));
let (remaining, parsed) = recognize(parser)(input)?; 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 /// Representing a decimal integer value in the range 0 through 255
/// ///
/// Snum = 1*3DIGIT /// 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) take_while_m_n(1, 3, is_digit)(input)
} }
/// IPv6-address-literal = "IPv6:" IPv6-addr /// IPv6-address-literal = "IPv6:" IPv6-addr
pub fn IPv6_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn ipv6_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((tag_no_case(b"IPv6:"), IPv6_addr)); let parser = tuple((tag_no_case(b"IPv6:"), ipv6_addr));
let (remaining, parsed) = recognize(parser)(input)?; 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 /// IPv6-addr = IPv6-full / IPv6-comp / IPv6v4-full / IPv6v4-comp
pub fn IPv6_addr(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn ipv6_addr(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = alt((IPv6_full, IPv6_comp, IPv6v4_full, IPv6v4_comp)); let parser = alt((ipv6_full, ipv6_comp, ipv6v4_full, ipv6v4_comp));
let (remaining, parsed) = recognize(parser)(input)?; 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) /// IPv6-full = IPv6-hex 7(":" IPv6-hex)
pub fn IPv6_full(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn ipv6_full(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((IPv6_hex, count(tuple((tag(b":"), IPv6_hex)), 7))); let parser = tuple((ipv6_hex, count(tuple((tag(b":"), ipv6_hex)), 7)));
let (remaining, parsed) = recognize(parser)(input)?; let (remaining, parsed) = recognize(parser)(input)?;
@ -77,7 +77,7 @@ pub fn IPv6_full(input: &[u8]) -> IResult<&[u8], &[u8]> {
} }
/// IPv6-hex = 1*4HEXDIG /// 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) 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. /// No more than 6 groups in addition to the "::" may be present.
/// ///
/// IPv6-comp = [IPv6-hex *5(":" IPv6-hex)] "::" [IPv6-hex *5(":" IPv6-hex)] /// 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(( let parser = tuple((
opt(tuple(( opt(tuple((
IPv6_hex, ipv6_hex,
many_m_n(0, 5, tuple((tag(b":"), IPv6_hex))), many_m_n(0, 5, tuple((tag(b":"), ipv6_hex))),
))), ))),
tag(b"::"), tag(b"::"),
opt(tuple(( opt(tuple((
IPv6_hex, ipv6_hex,
many_m_n(0, 5, tuple((tag(b":"), 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 /// 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(( let parser = tuple((
IPv6_hex, ipv6_hex,
count(tuple((tag(b":"), IPv6_hex)), 5), count(tuple((tag(b":"), ipv6_hex)), 5),
tag(b":"), tag(b":"),
IPv4_address_literal, ipv4_address_literal,
)); ));
let (remaining, parsed) = recognize(parser)(input)?; 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)] "::" /// IPv6v4-comp = [IPv6-hex *3(":" IPv6-hex)] "::"
/// [IPv6-hex *3(":" IPv6-hex) ":"] /// [IPv6-hex *3(":" IPv6-hex) ":"]
/// IPv4-address-literal /// IPv4-address-literal
pub fn IPv6v4_comp(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn ipv6v4_comp(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple(( let parser = tuple((
opt(tuple(( opt(tuple((
IPv6_hex, ipv6_hex,
many_m_n(0, 3, tuple((tag(b":"), IPv6_hex))), many_m_n(0, 3, tuple((tag(b":"), ipv6_hex))),
))), ))),
tag(b"::"), tag(b"::"),
opt(tuple(( opt(tuple((
IPv6_hex, ipv6_hex,
many_m_n(0, 3, tuple((tag(b":"), IPv6_hex))), many_m_n(0, 3, tuple((tag(b":"), ipv6_hex))),
tag(b":"), tag(b":"),
))), ))),
IPv4_address_literal, ipv4_address_literal,
)); ));
let (remaining, parsed) = recognize(parser)(input)?; 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 /// General-address-literal = Standardized-tag ":" 1*dcontent
pub fn General_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn general_address_literal(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((Standardized_tag, tag(b":"), take_while1(is_dcontent))); let parser = tuple((standardized_tag, tag(b":"), take_while1(is_dcontent)));
let (remaining, parsed) = recognize(parser)(input)?; 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 MUST be specified in a Standards-Track RFC and registered with IANA
/// ///
/// Standardized-tag = Ldh-str /// Standardized-tag = Ldh-str
pub fn Standardized_tag(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn standardized_tag(input: &[u8]) -> IResult<&[u8], &[u8]> {
Ldh_str(input) ldh_str(input)
} }
/// Printable US-ASCII excl. "[", "\", "]" /// Printable US-ASCII excl. "[", "\", "]"

View File

@ -9,7 +9,7 @@ use nom::{
}; };
use crate::{ 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}, types::{Command, DomainOrAddress, Parameter},
}; };
@ -28,7 +28,7 @@ pub fn helo(input: &[u8]) -> IResult<&[u8], Command> {
tag_no_case(b"HELO"), tag_no_case(b"HELO"),
tag(" "), tag(" "),
alt(( alt((
map(Domain, |domain| DomainOrAddress::Domain(domain.into())), map(domain, |domain| DomainOrAddress::Domain(domain.into())),
map(address_literal, |address| { map(address_literal, |address| {
DomainOrAddress::Address(address.into()) DomainOrAddress::Address(address.into())
}), }),
@ -47,7 +47,7 @@ pub fn ehlo(input: &[u8]) -> IResult<&[u8], Command> {
tag_no_case(b"EHLO"), tag_no_case(b"EHLO"),
tag(" "), tag(" "),
alt(( alt((
map(Domain, |domain| DomainOrAddress::Domain(domain.into())), map(domain, |domain| DomainOrAddress::Domain(domain.into())),
map(address_literal, |address| { map(address_literal, |address| {
DomainOrAddress::Address(address.into()) DomainOrAddress::Address(address.into())
}), }),
@ -65,8 +65,8 @@ pub fn mail(input: &[u8]) -> IResult<&[u8], Command> {
let mut parser = tuple(( let mut parser = tuple((
tag_no_case(b"MAIL FROM:"), tag_no_case(b"MAIL FROM:"),
opt(tag(" ")), // Out-of-tag(" ")ec, but Outlook does it ... opt(tag(" ")), // Out-of-tag(" ")ec, but Outlook does it ...
Reverse_path, reverse_path,
opt(preceded(tag(" "), Mail_parameters)), opt(preceded(tag(" "), mail_parameters)),
tag("\r\n"), tag("\r\n"),
)); ));
@ -82,7 +82,7 @@ pub fn mail(input: &[u8]) -> IResult<&[u8], Command> {
} }
/// Mail-parameters = esmtp-param *(tag(" ") esmtp-param) /// Mail-parameters = esmtp-param *(tag(" ") esmtp-param)
pub fn Mail_parameters(input: &[u8]) -> IResult<&[u8], Vec<Parameter>> { pub fn mail_parameters(input: &[u8]) -> IResult<&[u8], Vec<Parameter>> {
separated_list1(tag(" "), esmtp_param)(input) 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 ... opt(tag(" ")), // Out-of-tag(" ")ec, but Outlook does it ...
alt(( alt((
map_res( map_res(
recognize(tuple((tag_no_case("<Postmaster@"), Domain, tag(">")))), recognize(tuple((tag_no_case("<Postmaster@"), domain, tag(">")))),
std::str::from_utf8, std::str::from_utf8,
), ),
map_res(tag_no_case("<Postmaster>"), std::str::from_utf8), map_res(tag_no_case("<Postmaster>"), std::str::from_utf8),
Forward_path, forward_path,
)), )),
opt(preceded(tag(" "), Rcpt_parameters)), opt(preceded(tag(" "), rcpt_parameters)),
tag("\r\n"), tag("\r\n"),
)); ));
@ -160,7 +160,7 @@ pub fn rcpt(input: &[u8]) -> IResult<&[u8], Command> {
} }
/// Rcpt-parameters = esmtp-param *(tag(" ") esmtp-param) /// Rcpt-parameters = esmtp-param *(tag(" ") esmtp-param)
pub fn Rcpt_parameters(input: &[u8]) -> IResult<&[u8], Vec<Parameter>> { pub fn rcpt_parameters(input: &[u8]) -> IResult<&[u8], Vec<Parameter>> {
separated_list1(tag(" "), esmtp_param)(input) separated_list1(tag(" "), esmtp_param)(input)
} }
@ -176,7 +176,7 @@ pub fn rset(input: &[u8]) -> IResult<&[u8], Command> {
/// vrfy = "VRFY" tag(" ") String CRLF /// vrfy = "VRFY" tag(" ") String CRLF
pub fn vrfy(input: &[u8]) -> IResult<&[u8], Command> { 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)?; let (remaining, (_, _, data, _)) = parser(input)?;
@ -190,7 +190,7 @@ pub fn vrfy(input: &[u8]) -> IResult<&[u8], Command> {
/// expn = "EXPN" tag(" ") String CRLF /// expn = "EXPN" tag(" ") String CRLF
pub fn expn(input: &[u8]) -> IResult<&[u8], Command> { 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)?; 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> { pub fn help(input: &[u8]) -> IResult<&[u8], Command> {
let mut parser = tuple(( let mut parser = tuple((
tag_no_case(b"HELP"), tag_no_case(b"HELP"),
opt(preceded(tag(" "), String)), opt(preceded(tag(" "), string)),
tag("\r\n"), tag("\r\n"),
)); ));
@ -219,7 +219,7 @@ pub fn help(input: &[u8]) -> IResult<&[u8], Command> {
pub fn noop(input: &[u8]) -> IResult<&[u8], Command> { pub fn noop(input: &[u8]) -> IResult<&[u8], Command> {
let mut parser = tuple(( let mut parser = tuple((
tag_no_case(b"NOOP"), tag_no_case(b"NOOP"),
opt(preceded(tag(" "), String)), opt(preceded(tag(" "), string)),
tag("\r\n"), tag("\r\n"),
)); ));
@ -240,7 +240,7 @@ pub fn quit(input: &[u8]) -> IResult<&[u8], Command> {
pub fn starttls(input: &[u8]) -> IResult<&[u8], Command> { pub fn starttls(input: &[u8]) -> IResult<&[u8], Command> {
value( value(
Command::StartTLS, Command::StartTls,
tuple((tag_no_case(b"STARTTLS"), tag("\r\n"))), tuple((tag_no_case(b"STARTTLS"), tag("\r\n"))),
)(input) )(input)
} }
@ -293,21 +293,21 @@ pub fn auth_plain(input: &[u8]) -> IResult<&[u8], Command> {
// ----- 4.1.2. Command Argument Syntax (RFC 5321) ----- // ----- 4.1.2. Command Argument Syntax (RFC 5321) -----
/// Reverse-path = Path / "<>" /// Reverse-path = Path / "<>"
pub fn Reverse_path(input: &[u8]) -> IResult<&[u8], &str> { pub fn reverse_path(input: &[u8]) -> IResult<&[u8], &str> {
alt((Path, value("", tag("<>"))))(input) alt((path, value("", tag("<>"))))(input)
} }
/// Forward-path = Path /// Forward-path = Path
pub fn Forward_path(input: &[u8]) -> IResult<&[u8], &str> { pub fn forward_path(input: &[u8]) -> IResult<&[u8], &str> {
Path(input) path(input)
} }
// Path = "<" [ A-d-l ":" ] Mailbox ">" // Path = "<" [ A-d-l ":" ] Mailbox ">"
pub fn Path(input: &[u8]) -> IResult<&[u8], &str> { pub fn path(input: &[u8]) -> IResult<&[u8], &str> {
delimited( delimited(
tag(b"<"), tag(b"<"),
map_res( 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, std::str::from_utf8,
), ),
tag(b">"), tag(b">"),
@ -318,8 +318,8 @@ pub fn Path(input: &[u8]) -> IResult<&[u8], &str> {
/// ; Note that this form, the so-called "source /// ; Note that this form, the so-called "source
/// ; route", MUST BE accepted, SHOULD NOT be /// ; route", MUST BE accepted, SHOULD NOT be
/// ; generated, and SHOULD be ignored. /// ; generated, and SHOULD be ignored.
pub fn A_d_l(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn a_d_l(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = separated_list1(tag(b","), At_domain); let parser = separated_list1(tag(b","), at_domain);
let (remaining, parsed) = recognize(parser)(input)?; let (remaining, parsed) = recognize(parser)(input)?;
@ -327,8 +327,8 @@ pub fn A_d_l(input: &[u8]) -> IResult<&[u8], &[u8]> {
} }
/// At-domain = "@" Domain /// At-domain = "@" Domain
pub fn At_domain(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn at_domain(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((tag(b"@"), Domain)); let parser = tuple((tag(b"@"), domain));
let (remaining, parsed) = recognize(parser)(input)?; 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 ) /// Mailbox = Local-part "@" ( Domain / address-literal )
pub fn Mailbox(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn mailbox(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = tuple((Local_part, tag(b"@"), alt((Domain, address_literal)))); let parser = tuple((local_part, tag(b"@"), alt((domain, address_literal))));
let (remaining, parsed) = recognize(parser)(input)?; let (remaining, parsed) = recognize(parser)(input)?;
@ -346,14 +346,14 @@ pub fn Mailbox(input: &[u8]) -> IResult<&[u8], &[u8]> {
/// Local-part = Dot-string / Quoted-string /// Local-part = Dot-string / Quoted-string
/// ; MAY be case-sensitive /// ; MAY be case-sensitive
pub fn Local_part(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn local_part(input: &[u8]) -> IResult<&[u8], &[u8]> {
alt((recognize(Dot_string), recognize(Quoted_string)))(input) alt((recognize(dot_string), recognize(quoted_string)))(input)
} }
/// Dot-string = Atom *("." Atom) /// Dot-string = Atom *("." Atom)
pub fn Dot_string(input: &[u8]) -> IResult<&[u8], &str> { pub fn dot_string(input: &[u8]) -> IResult<&[u8], &str> {
map_res( map_res(
recognize(separated_list1(tag(b"."), Atom)), recognize(separated_list1(tag(b"."), atom)),
std::str::from_utf8, std::str::from_utf8,
)(input) )(input)
} }

View File

@ -1,5 +1,3 @@
#![allow(non_snake_case)]
use std::{borrow::Cow, str::from_utf8}; use std::{borrow::Cow, str::from_utf8};
use nom::{ use nom::{
@ -44,15 +42,15 @@ pub fn number(input: &[u8]) -> IResult<&[u8], u32> {
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
/// String = Atom / Quoted-string /// String = Atom / Quoted-string
pub fn String(input: &[u8]) -> IResult<&[u8], AtomOrQuoted> { pub fn string(input: &[u8]) -> IResult<&[u8], AtomOrQuoted> {
alt(( alt((
map(Atom, |atom| AtomOrQuoted::Atom(atom.into())), map(atom, |atom| AtomOrQuoted::Atom(atom.into())),
map(Quoted_string, |quoted| AtomOrQuoted::Quoted(quoted.into())), map(quoted_string, |quoted| AtomOrQuoted::Quoted(quoted.into())),
))(input) ))(input)
} }
/// Atom = 1*atext /// 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) 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 /// 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( map(
delimited( delimited(
tag("\""), tag("\""),
map_res(recognize(many0(QcontentSMTP)), std::str::from_utf8), map_res(recognize(many0(q_content_smtp)), std::str::from_utf8),
tag("\""), tag("\""),
), ),
unescape_quoted, unescape_quoted,
@ -89,8 +87,8 @@ pub fn Quoted_string(input: &[u8]) -> IResult<&[u8], Cow<'_, str>> {
} }
/// QcontentSMTP = qtextSMTP / quoted-pairSMTP /// QcontentSMTP = qtextSMTP / quoted-pairSMTP
pub fn QcontentSMTP(input: &[u8]) -> IResult<&[u8], &[u8]> { pub fn q_content_smtp(input: &[u8]) -> IResult<&[u8], &[u8]> {
let parser = alt((take_while_m_n(1, 1, is_qtextSMTP), quoted_pairSMTP)); let parser = alt((take_while_m_n(1, 1, is_qtext_smtp), quoted_pair_smtp));
let (remaining, parsed) = recognize(parser)(input)?; 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. /// without blackslash-quoting except double-quote and the backslash itself.
/// ///
/// qtextSMTP = %d32-33 / %d35-91 / %d93-126 /// 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) matches!(byte, 32..=33 | 35..=91 | 93..=126)
} }
@ -110,7 +108,7 @@ pub fn is_qtextSMTP(byte: u8) -> bool {
/// quoted-pairSMTP = %d92 %d32-126 /// quoted-pairSMTP = %d92 %d32-126
/// ///
/// FIXME: How should e.g. "\a" be interpreted? /// 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 { //fn is_value(byte: u8) -> bool {
// matches!(byte, 32..=126) // matches!(byte, 32..=126)
//} //}
@ -130,7 +128,7 @@ pub fn quoted_pairSMTP(input: &[u8]) -> IResult<&[u8], &[u8]> {
// ------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------
/// Domain = sub-domain *("." sub-domain) /// 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 parser = separated_list1(tag(b"."), sub_domain);
let (remaining, parsed) = map_res(recognize(parser), std::str::from_utf8)(input)?; 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] /// sub-domain = Let-dig [Ldh-str]
pub fn sub_domain(input: &[u8]) -> IResult<&[u8], &[u8]> { 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)?; let (remaining, parsed) = recognize(parser)(input)?;
@ -148,16 +146,16 @@ pub fn sub_domain(input: &[u8]) -> IResult<&[u8], &[u8]> {
} }
/// Let-dig = ALPHA / DIGIT /// 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) is_alphabetic(byte) || is_digit(byte)
} }
/// Ldh-str = *( ALPHA / DIGIT / "-" ) Let-dig /// 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(( let parser = many0(alt((
take_while_m_n(1, 1, is_alphabetic), take_while_m_n(1, 1, is_alphabetic),
take_while_m_n(1, 1, is_digit), 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)?; let (remaining, parsed) = recognize(parser)(input)?;

View File

@ -11,7 +11,7 @@ use nom::{
}; };
use crate::{ use crate::{
parse::{address::address_literal, number, Domain}, parse::{address::address_literal, domain, number},
types::{AuthMechanism, Capability, ReplyCode, Response, TextString}, types::{AuthMechanism, Capability, ReplyCode, Response, TextString},
}; };
@ -19,12 +19,12 @@ use crate::{
/// ( "220-" (Domain / address-literal) [ SP textstring ] CRLF /// ( "220-" (Domain / address-literal) [ SP textstring ] CRLF
/// *( "220-" [ textstring ] CRLF ) /// *( "220-" [ textstring ] CRLF )
/// "220" [ SP 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(( let mut parser = alt((
map( map(
tuple(( tuple((
tag(b"220 "), tag(b"220 "),
alt((Domain, address_literal)), alt((domain, address_literal)),
opt(preceded(tag(" "), textstring)), opt(preceded(tag(" "), textstring)),
tag("\r\n"), tag("\r\n"),
)), )),
@ -38,7 +38,7 @@ pub fn Greeting(input: &[u8]) -> IResult<&[u8], Response> {
map( map(
tuple(( tuple((
tag(b"220-"), tag(b"220-"),
alt((Domain, address_literal)), alt((domain, address_literal)),
opt(preceded(tag(" "), textstring)), opt(preceded(tag(" "), textstring)),
tag("\r\n"), tag("\r\n"),
many0(delimited(tag(b"220-"), opt(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-line = *( Reply-code "-" [ textstring ] CRLF )
/// Reply-code [ SP 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( let mut parser = map(
tuple(( tuple((
many0(tuple((Reply_code, tag(b"-"), opt(textstring), tag("\r\n")))), many0(tuple((reply_code, tag(b"-"), opt(textstring), tag("\r\n")))),
Reply_code, reply_code,
opt(tuple((tag(" "), textstring))), opt(tuple((tag(" "), textstring))),
tag("\r\n"), tag("\r\n"),
)), )),
@ -129,7 +129,7 @@ pub fn Reply_lines(input: &[u8]) -> IResult<&[u8], Response> {
/// 2345 /// 2345
/// 012345 /// 012345
/// 0123456789 /// 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. // FIXME: do not accept all codes.
map_res( map_res(
map_res( map_res(
@ -153,7 +153,7 @@ pub fn ehlo_ok_rsp(input: &[u8]) -> IResult<&[u8], Response> {
map( map(
tuple(( tuple((
tag(b"250 "), tag(b"250 "),
Domain, domain,
opt(preceded(tag(" "), ehlo_greet)), opt(preceded(tag(" "), ehlo_greet)),
tag("\r\n"), tag("\r\n"),
)), )),
@ -166,7 +166,7 @@ pub fn ehlo_ok_rsp(input: &[u8]) -> IResult<&[u8], Response> {
map( map(
tuple(( tuple((
tag(b"250-"), tag(b"250-"),
Domain, domain,
opt(preceded(tag(" "), ehlo_greet)), opt(preceded(tag(" "), ehlo_greet)),
tag("\r\n"), tag("\r\n"),
many0(delimited(tag(b"250-"), ehlo_line, 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(( alt((
value(Capability::EXPN, tag_no_case("EXPN")), value(Capability::Expn, tag_no_case("EXPN")),
value(Capability::Help, tag_no_case("HELP")), 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), map(preceded(tag_no_case("SIZE "), number), Capability::Size),
value(Capability::Chunking, tag_no_case("CHUNKING")), 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::Checkpoint, tag_no_case("CHECKPOINT")),
value(Capability::DeliverBy, tag_no_case("DELIVERBY")), value(Capability::DeliverBy, tag_no_case("DELIVERBY")),
value(Capability::Pipelining, tag_no_case("PIPELINING")), value(Capability::Pipelining, tag_no_case("PIPELINING")),
value(Capability::DSN, tag_no_case("DSN")), value(Capability::Dsn, tag_no_case("DSN")),
value(Capability::ETRN, tag_no_case("ETRN")), value(Capability::Etrn, tag_no_case("ETRN")),
value( value(
Capability::EnhancedStatusCodes, Capability::EnhancedStatusCodes,
tag_no_case("ENHANCEDSTATUSCODES"), tag_no_case("ENHANCEDSTATUSCODES"),
), ),
value(Capability::StartTLS, tag_no_case("STARTTLS")), value(Capability::StartTls, tag_no_case("STARTTLS")),
// FIXME: NO-SOLICITING // FIXME: NO-SOLICITING
value(Capability::MTRK, tag_no_case("MTRK")), value(Capability::Mtrk, tag_no_case("MTRK")),
value(Capability::ATRN, tag_no_case("ATRN")), value(Capability::Atrn, tag_no_case("ATRN")),
map(auth, |(_, _, mechanisms)| Capability::Auth(mechanisms)), map(auth, |(_, _, mechanisms)| Capability::Auth(mechanisms)),
value(Capability::BURL, tag_no_case("BURL")), value(Capability::Burl, tag_no_case("BURL")),
// FIXME: FUTURERELEASE // FIXME: FUTURERELEASE
// FIXME: CONPERM // FIXME: CONPERM
// FIXME: CONNEG // FIXME: CONNEG
value(Capability::SMTPUTF8, tag_no_case("SMTPUTF8")), value(Capability::SmtpUtf8, tag_no_case("SMTPUTF8")),
// FIXME: MT-PRIORITY // FIXME: MT-PRIORITY
value(Capability::RRVS, tag_no_case("RRVS")), value(Capability::Rrvs, tag_no_case("RRVS")),
value(Capability::RequireTLS, tag_no_case("REQUIRETLS")), value(Capability::RequireTls, tag_no_case("REQUIRETLS")),
map(other, |(keyword, params)| Capability::Other { map(other, |(keyword, params)| Capability::Other {
keyword: keyword.into(), keyword: keyword.into(),
params: params params: params
@ -287,12 +287,12 @@ pub fn auth_mechanism(input: &[u8]) -> IResult<&[u8], AuthMechanism> {
alt(( alt((
value(AuthMechanism::Login, tag_no_case("LOGIN")), value(AuthMechanism::Login, tag_no_case("LOGIN")),
value(AuthMechanism::Plain, tag_no_case("PLAIN")), value(AuthMechanism::Plain, tag_no_case("PLAIN")),
value(AuthMechanism::CramMD5, tag_no_case("CRAM-MD5")), value(AuthMechanism::CramMd5, tag_no_case("CRAM-MD5")),
value(AuthMechanism::CramSHA1, tag_no_case("CRAM-SHA1")), value(AuthMechanism::CramSha1, tag_no_case("CRAM-SHA1")),
value(AuthMechanism::DigestMD5, tag_no_case("DIGEST-MD5")), value(AuthMechanism::DigestMd5, tag_no_case("DIGEST-MD5")),
value(AuthMechanism::ScramMD5, tag_no_case("SCRAM-MD5")), value(AuthMechanism::ScramMd5, tag_no_case("SCRAM-MD5")),
value(AuthMechanism::GSSAPI, tag_no_case("GSSAPI")), value(AuthMechanism::GssApi, tag_no_case("GSSAPI")),
value(AuthMechanism::NTLM, tag_no_case("NTLM")), value(AuthMechanism::Ntlm, tag_no_case("NTLM")),
map(ehlo_param, |param| AuthMechanism::Other(param.to_string())), map(ehlo_param, |param| AuthMechanism::Other(param.to_string())),
))(input) ))(input)
} }
@ -305,12 +305,12 @@ mod test {
use crate::types::AuthMechanism; use crate::types::AuthMechanism;
#[test] #[test]
fn test_Greeting() { fn test_greeting() {
let greeting = b"220-example.org ESMTP Fake 4.93 #2 Thu, 16 Jul 2020 07:30:16 -0400\r\n\ 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-We do not authorize the use of this system to transport unsolicited,\r\n\
220 and/or bulk e-mail.\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!(rem, b"");
assert_eq!( assert_eq!(
out, out,
@ -344,17 +344,17 @@ and/or bulk e-mail."
capabilities: vec![ capabilities: vec![
Capability::Auth(vec![ Capability::Auth(vec![
AuthMechanism::Login, AuthMechanism::Login,
AuthMechanism::CramMD5, AuthMechanism::CramMd5,
AuthMechanism::Plain AuthMechanism::Plain
]), ]),
Capability::Auth(vec![ Capability::Auth(vec![
AuthMechanism::Login, AuthMechanism::Login,
AuthMechanism::CramMD5, AuthMechanism::CramMd5,
AuthMechanism::Plain AuthMechanism::Plain
]), ]),
Capability::StartTLS, Capability::StartTls,
Capability::Size(12345), Capability::Size(12345),
Capability::EightBitMIME, Capability::EightBitMime,
], ],
} }
); );

View File

@ -89,7 +89,7 @@ pub enum Command {
/// mail transaction will be aborted. /// mail transaction will be aborted.
Quit, Quit,
// Extensions // Extensions
StartTLS, StartTls,
// AUTH LOGIN // AUTH LOGIN
AuthLogin(Option<String>), AuthLogin(Option<String>),
// AUTH PLAIN // AUTH PLAIN
@ -149,7 +149,7 @@ impl Command {
Command::Noop { .. } => "NOOP", Command::Noop { .. } => "NOOP",
Command::Quit => "QUIT", Command::Quit => "QUIT",
// Extensions // Extensions
Command::StartTLS => "STARTTLS", Command::StartTls => "STARTTLS",
// TODO: SMTP AUTH LOGIN // TODO: SMTP AUTH LOGIN
Command::AuthLogin(_) => "AUTHLOGIN", Command::AuthLogin(_) => "AUTHLOGIN",
// TODO: SMTP AUTH PLAIN // TODO: SMTP AUTH PLAIN
@ -233,7 +233,7 @@ impl Command {
Quit => writer.write_all(b"QUIT")?, Quit => writer.write_all(b"QUIT")?,
// ----- Extensions ----- // ----- Extensions -----
// starttls = "STARTTLS" CRLF // starttls = "STARTTLS" CRLF
StartTLS => writer.write_all(b"STARTTLS")?, StartTls => writer.write_all(b"STARTTLS")?,
// auth_login_command = "AUTH LOGIN" [SP username] CRLF // auth_login_command = "AUTH LOGIN" [SP username] CRLF
AuthLogin(None) => { AuthLogin(None) => {
writer.write_all(b"AUTH LOGIN")?; writer.write_all(b"AUTH LOGIN")?;
@ -316,7 +316,7 @@ pub enum Response {
impl Response { impl Response {
pub fn parse_greeting(input: &[u8]) -> IResult<&[u8], Self> { pub fn parse_greeting(input: &[u8]) -> IResult<&[u8], Self> {
crate::parse::response::Greeting(input) crate::parse::response::greeting(input)
} }
pub fn greeting<D, T>(domain: D, text: T) -> Response pub fn greeting<D, T>(domain: D, text: T) -> Response
@ -335,7 +335,7 @@ impl Response {
} }
pub fn parse_other(input: &[u8]) -> IResult<&[u8], Self> { pub fn parse_other(input: &[u8]) -> IResult<&[u8], Self> {
crate::parse::response::Reply_lines(input) crate::parse::response::reply_lines(input)
} }
pub fn ehlo<D, G>(domain: D, greet: Option<G>, capabilities: Vec<Capability>) -> Response pub fn ehlo<D, G>(domain: D, greet: Option<G>, capabilities: Vec<Capability>) -> Response
@ -465,13 +465,13 @@ pub enum Capability {
/// Expand the mailing list [RFC821] /// Expand the mailing list [RFC821]
/// Command description updated by [RFC5321] /// Command description updated by [RFC5321]
EXPN, Expn,
/// Supply helpful information [RFC821] /// Supply helpful information [RFC821]
/// Command description updated by [RFC5321] /// Command description updated by [RFC5321]
Help, Help,
/// SMTP and Submit transport of 8bit MIME content [RFC6152] /// SMTP and Submit transport of 8bit MIME content [RFC6152]
EightBitMIME, EightBitMime,
/// Message size declaration [RFC1870] /// Message size declaration [RFC1870]
Size(u32), Size(u32),
@ -480,7 +480,7 @@ pub enum Capability {
Chunking, Chunking,
/// Binary MIME [RFC3030] /// Binary MIME [RFC3030]
BinaryMIME, BinaryMime,
/// Checkpoint/Restart [RFC1845] /// Checkpoint/Restart [RFC1845]
Checkpoint, Checkpoint,
@ -492,34 +492,34 @@ pub enum Capability {
Pipelining, Pipelining,
/// Delivery Status Notification [RFC3461] /// Delivery Status Notification [RFC3461]
DSN, Dsn,
/// Extended Turn [RFC1985] /// Extended Turn [RFC1985]
/// SMTP [RFC5321] only. Not for use on Submit port 587. /// SMTP [RFC5321] only. Not for use on Submit port 587.
ETRN, Etrn,
/// Enhanced Status Codes [RFC2034] /// Enhanced Status Codes [RFC2034]
EnhancedStatusCodes, EnhancedStatusCodes,
/// Start TLS [RFC3207] /// Start TLS [RFC3207]
StartTLS, StartTls,
/// Notification of no soliciting [RFC3865] /// Notification of no soliciting [RFC3865]
// NoSoliciting, // NoSoliciting,
/// Message Tracking [RFC3885] /// Message Tracking [RFC3885]
MTRK, Mtrk,
/// Authenticated TURN [RFC2645] /// Authenticated TURN [RFC2645]
/// SMTP [RFC5321] only. Not for use on Submit port 587. /// SMTP [RFC5321] only. Not for use on Submit port 587.
ATRN, Atrn,
/// Authentication [RFC4954] /// Authentication [RFC4954]
Auth(Vec<AuthMechanism>), Auth(Vec<AuthMechanism>),
/// Remote Content [RFC4468] /// Remote Content [RFC4468]
/// Submit [RFC6409] only. Not for use with SMTP on port 25. /// Submit [RFC6409] only. Not for use with SMTP on port 25.
BURL, Burl,
/// Future Message Release [RFC4865] /// Future Message Release [RFC4865]
// FutureRelease, // FutureRelease,
@ -531,16 +531,16 @@ pub enum Capability {
// ConNeg, // ConNeg,
/// Internationalized email address [RFC6531] /// Internationalized email address [RFC6531]
SMTPUTF8, SmtpUtf8,
/// Priority Message Handling [RFC6710] /// Priority Message Handling [RFC6710]
// MTPRIORITY, // MTPRIORITY,
/// Require Recipient Valid Since [RFC7293] /// Require Recipient Valid Since [RFC7293]
RRVS, Rrvs,
/// Require TLS [RFC8689] /// Require TLS [RFC8689]
RequireTLS, RequireTls,
// Observed ... // Observed ...
// TIME, // TIME,
@ -557,21 +557,21 @@ pub enum Capability {
impl Capability { impl Capability {
pub fn serialize(&self, writer: &mut impl Write) -> std::io::Result<()> { pub fn serialize(&self, writer: &mut impl Write) -> std::io::Result<()> {
match self { match self {
Capability::EXPN => writer.write_all(b"EXPN"), Capability::Expn => writer.write_all(b"EXPN"),
Capability::Help => writer.write_all(b"HELP"), 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::Size(number) => writer.write_all(format!("SIZE {}", number).as_bytes()),
Capability::Chunking => writer.write_all(b"CHUNKING"), 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::Checkpoint => writer.write_all(b"CHECKPOINT"),
Capability::DeliverBy => writer.write_all(b"DELIVERBY"), Capability::DeliverBy => writer.write_all(b"DELIVERBY"),
Capability::Pipelining => writer.write_all(b"PIPELINING"), Capability::Pipelining => writer.write_all(b"PIPELINING"),
Capability::DSN => writer.write_all(b"DSN"), Capability::Dsn => writer.write_all(b"DSN"),
Capability::ETRN => writer.write_all(b"ETRN"), Capability::Etrn => writer.write_all(b"ETRN"),
Capability::EnhancedStatusCodes => writer.write_all(b"ENHANCEDSTATUSCODES"), Capability::EnhancedStatusCodes => writer.write_all(b"ENHANCEDSTATUSCODES"),
Capability::StartTLS => writer.write_all(b"STARTTLS"), Capability::StartTls => writer.write_all(b"STARTTLS"),
Capability::MTRK => writer.write_all(b"MTRK"), Capability::Mtrk => writer.write_all(b"MTRK"),
Capability::ATRN => writer.write_all(b"ATRN"), Capability::Atrn => writer.write_all(b"ATRN"),
Capability::Auth(mechanisms) => { Capability::Auth(mechanisms) => {
if let Some((tail, head)) = mechanisms.split_last() { if let Some((tail, head)) = mechanisms.split_last() {
writer.write_all(b"AUTH ")?; writer.write_all(b"AUTH ")?;
@ -586,10 +586,10 @@ impl Capability {
writer.write_all(b"AUTH") writer.write_all(b"AUTH")
} }
} }
Capability::BURL => writer.write_all(b"BURL"), Capability::Burl => writer.write_all(b"BURL"),
Capability::SMTPUTF8 => writer.write_all(b"SMTPUTF8"), Capability::SmtpUtf8 => writer.write_all(b"SMTPUTF8"),
Capability::RRVS => writer.write_all(b"RRVS"), Capability::Rrvs => writer.write_all(b"RRVS"),
Capability::RequireTLS => writer.write_all(b"REQUIRETLS"), Capability::RequireTls => writer.write_all(b"REQUIRETLS"),
Capability::Other { keyword, params } => { Capability::Other { keyword, params } => {
if let Some((tail, head)) = params.split_last() { if let Some((tail, head)) = params.split_last() {
writer.write_all(keyword.as_bytes())?; writer.write_all(keyword.as_bytes())?;
@ -773,13 +773,13 @@ impl From<ReplyCode> for u16 {
pub enum AuthMechanism { pub enum AuthMechanism {
Plain, Plain,
Login, Login,
GSSAPI, GssApi,
CramMD5, CramMd5,
CramSHA1, CramSha1,
ScramMD5, ScramMd5,
DigestMD5, DigestMd5,
NTLM, Ntlm,
Other(String), Other(String),
} }
@ -789,13 +789,13 @@ impl AuthMechanism {
match self { match self {
AuthMechanism::Plain => writer.write_all(b"PLAIN"), AuthMechanism::Plain => writer.write_all(b"PLAIN"),
AuthMechanism::Login => writer.write_all(b"LOGIN"), 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::CramMd5 => writer.write_all(b"CRAM-MD5"),
AuthMechanism::CramSHA1 => writer.write_all(b"CRAM-SHA1"), AuthMechanism::CramSha1 => writer.write_all(b"CRAM-SHA1"),
AuthMechanism::ScramMD5 => writer.write_all(b"SCRAM-MD5"), AuthMechanism::ScramMd5 => writer.write_all(b"SCRAM-MD5"),
AuthMechanism::DigestMD5 => writer.write_all(b"DIGEST-MD5"), AuthMechanism::DigestMd5 => writer.write_all(b"DIGEST-MD5"),
AuthMechanism::NTLM => writer.write_all(b"NTLM"), AuthMechanism::Ntlm => writer.write_all(b"NTLM"),
AuthMechanism::Other(other) => writer.write_all(other.as_bytes()), AuthMechanism::Other(other) => writer.write_all(other.as_bytes()),
} }
@ -912,7 +912,7 @@ mod tests {
Response::Ehlo { Response::Ehlo {
domain: "example.org".into(), domain: "example.org".into(),
greet: Some("...".into()), greet: Some("...".into()),
capabilities: vec![Capability::StartTLS], capabilities: vec![Capability::StartTls],
}, },
b"250-example.org ...\r\n250 STARTTLS\r\n".as_ref(), b"250-example.org ...\r\n250 STARTTLS\r\n".as_ref(),
), ),
@ -920,7 +920,7 @@ mod tests {
Response::Ehlo { Response::Ehlo {
domain: "example.org".into(), domain: "example.org".into(),
greet: Some("...".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(), b"250-example.org ...\r\n250-STARTTLS\r\n250 SIZE 12345\r\n".as_ref(),
), ),