Stick to idiomatic naming conventions
This commit is contained in:
parent
263c2c16cd
commit
351990b95e
|
@ -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. "[", "\", "]"
|
||||
|
|
|
@ -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<Parameter>> {
|
||||
pub fn mail_parameters(input: &[u8]) -> IResult<&[u8], Vec<Parameter>> {
|
||||
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("<Postmaster@"), Domain, tag(">")))),
|
||||
recognize(tuple((tag_no_case("<Postmaster@"), domain, tag(">")))),
|
||||
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"),
|
||||
));
|
||||
|
||||
|
@ -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<Parameter>> {
|
||||
pub fn rcpt_parameters(input: &[u8]) -> IResult<&[u8], Vec<Parameter>> {
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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,
|
||||
],
|
||||
}
|
||||
);
|
||||
|
|
86
src/types.rs
86
src/types.rs
|
@ -89,7 +89,7 @@ pub enum Command {
|
|||
/// mail transaction will be aborted.
|
||||
Quit,
|
||||
// Extensions
|
||||
StartTLS,
|
||||
StartTls,
|
||||
// AUTH LOGIN
|
||||
AuthLogin(Option<String>),
|
||||
// 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<D, T>(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<D, G>(domain: D, greet: Option<G>, capabilities: Vec<Capability>) -> 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<AuthMechanism>),
|
||||
|
||||
/// 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<ReplyCode> 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(),
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue