Improve fields of Command enum.
This commit is contained in:
parent
b8448a8889
commit
facfa4d7ea
|
@ -40,7 +40,12 @@ pub fn helo(input: &[u8]) -> IResult<&[u8], Command> {
|
|||
|
||||
let (remaining, (_, _, data, _)) = parser(input)?;
|
||||
|
||||
Ok((remaining, Command::Helo(data.into())))
|
||||
Ok((
|
||||
remaining,
|
||||
Command::Helo {
|
||||
fqdn_or_address_literal: data.into(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// ehlo = "EHLO" SP ( Domain / address-literal ) CRLF
|
||||
|
@ -54,7 +59,12 @@ pub fn ehlo(input: &[u8]) -> IResult<&[u8], Command> {
|
|||
|
||||
let (remaining, (_, _, data, _)) = parser(input)?;
|
||||
|
||||
Ok((remaining, Command::Ehlo(data.into())))
|
||||
Ok((
|
||||
remaining,
|
||||
Command::Ehlo {
|
||||
fqdn_or_address_literal: data.into(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// mail = "MAIL FROM:" Reverse-path [SP Mail-parameters] CRLF
|
||||
|
@ -72,8 +82,8 @@ pub fn mail(input: &[u8]) -> IResult<&[u8], Command> {
|
|||
Ok((
|
||||
remaining,
|
||||
Command::Mail {
|
||||
data: data.into(),
|
||||
params: maybe_params.map(|params| params.into()),
|
||||
reverse_path: data.into(),
|
||||
parameters: maybe_params.map(|params| params.into()),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
@ -101,8 +111,8 @@ pub fn rcpt(input: &[u8]) -> IResult<&[u8], Command> {
|
|||
Ok((
|
||||
remaining,
|
||||
Command::Rcpt {
|
||||
data: data.into(),
|
||||
params: maybe_params.map(|params| params.into()),
|
||||
forward_path: data.into(),
|
||||
parameters: maybe_params.map(|params| params.into()),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
@ -131,7 +141,12 @@ pub fn vrfy(input: &[u8]) -> IResult<&[u8], Command> {
|
|||
|
||||
let (remaining, (_, _, data, _)) = parser(input)?;
|
||||
|
||||
Ok((remaining, Command::Vrfy(data.into())))
|
||||
Ok((
|
||||
remaining,
|
||||
Command::Vrfy {
|
||||
user_or_mailbox: data.into(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// expn = "EXPN" SP String CRLF
|
||||
|
@ -140,7 +155,12 @@ pub fn expn(input: &[u8]) -> IResult<&[u8], Command> {
|
|||
|
||||
let (remaining, (_, _, data, _)) = parser(input)?;
|
||||
|
||||
Ok((remaining, Command::Expn(data.into())))
|
||||
Ok((
|
||||
remaining,
|
||||
Command::Expn {
|
||||
mailing_list: data.into(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// help = "HELP" [ SP String ] CRLF
|
||||
|
@ -149,7 +169,12 @@ pub fn help(input: &[u8]) -> IResult<&[u8], Command> {
|
|||
|
||||
let (remaining, (_, maybe_data, _)) = parser(input)?;
|
||||
|
||||
Ok((remaining, Command::Help(maybe_data.map(|data| data.into()))))
|
||||
Ok((
|
||||
remaining,
|
||||
Command::Help {
|
||||
argument: maybe_data.map(|data| data.into()),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// noop = "NOOP" [ SP String ] CRLF
|
||||
|
@ -158,7 +183,12 @@ pub fn noop(input: &[u8]) -> IResult<&[u8], Command> {
|
|||
|
||||
let (remaining, (_, maybe_data, _)) = parser(input)?;
|
||||
|
||||
Ok((remaining, Command::Noop(maybe_data.map(|data| data.into()))))
|
||||
Ok((
|
||||
remaining,
|
||||
Command::Noop {
|
||||
argument: maybe_data.map(|data| data.into()),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
/// quit = "QUIT" CRLF
|
||||
|
@ -512,14 +542,24 @@ mod test {
|
|||
#[test]
|
||||
fn test_ehlo() {
|
||||
let (rem, parsed) = ehlo(b"EHLO [123.123.123.123]\r\n???").unwrap();
|
||||
assert_eq!(parsed, Command::Ehlo(b"123.123.123.123".to_vec()));
|
||||
assert_eq!(
|
||||
parsed,
|
||||
Command::Ehlo {
|
||||
fqdn_or_address_literal: b"123.123.123.123".to_vec()
|
||||
}
|
||||
);
|
||||
assert_eq!(rem, b"???");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_helo() {
|
||||
let (rem, parsed) = helo(b"HELO example.com\r\n???").unwrap();
|
||||
assert_eq!(parsed, Command::Helo(b"example.com".to_vec()));
|
||||
assert_eq!(
|
||||
parsed,
|
||||
Command::Helo {
|
||||
fqdn_or_address_literal: b"example.com".to_vec()
|
||||
}
|
||||
);
|
||||
assert_eq!(rem, b"???");
|
||||
}
|
||||
|
||||
|
@ -529,8 +569,8 @@ mod test {
|
|||
assert_eq!(
|
||||
parsed,
|
||||
Command::Mail {
|
||||
data: b"<userx@y.foo.org>".to_vec(),
|
||||
params: None
|
||||
reverse_path: b"<userx@y.foo.org>".to_vec(),
|
||||
parameters: None
|
||||
}
|
||||
);
|
||||
assert_eq!(rem, b"???");
|
||||
|
|
137
src/types.rs
137
src/types.rs
|
@ -1,23 +1,86 @@
|
|||
use crate::escape;
|
||||
use std::io::Write;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub enum Command {
|
||||
Ehlo(Vec<u8>),
|
||||
Helo(Vec<u8>),
|
||||
Ehlo {
|
||||
fqdn_or_address_literal: Vec<u8>,
|
||||
},
|
||||
Helo {
|
||||
fqdn_or_address_literal: Vec<u8>,
|
||||
},
|
||||
Mail {
|
||||
data: Vec<u8>,
|
||||
params: Option<Vec<u8>>,
|
||||
reverse_path: Vec<u8>,
|
||||
parameters: Option<Vec<u8>>,
|
||||
},
|
||||
Rcpt {
|
||||
data: Vec<u8>,
|
||||
params: Option<Vec<u8>>,
|
||||
forward_path: Vec<u8>,
|
||||
parameters: Option<Vec<u8>>,
|
||||
},
|
||||
Data,
|
||||
Rset,
|
||||
Vrfy(Vec<u8>),
|
||||
Expn(Vec<u8>),
|
||||
Help(Option<Vec<u8>>),
|
||||
Noop(Option<Vec<u8>>),
|
||||
/// This command asks the receiver to confirm that the argument
|
||||
/// identifies a user or mailbox. If it is a user name, information is
|
||||
/// returned as specified in Section 3.5.
|
||||
///
|
||||
/// This command has no effect on the reverse-path buffer, the forward-
|
||||
/// path buffer, or the mail data buffer.
|
||||
Vrfy {
|
||||
user_or_mailbox: Vec<u8>,
|
||||
},
|
||||
/// This command asks the receiver to confirm that the argument
|
||||
/// identifies a mailing list, and if so, to return the membership of
|
||||
/// that list. If the command is successful, a reply is returned
|
||||
/// containing information as described in Section 3.5. This reply will
|
||||
/// have multiple lines except in the trivial case of a one-member list.
|
||||
///
|
||||
/// This command has no effect on the reverse-path buffer, the forward-
|
||||
/// path buffer, or the mail data buffer, and it may be issued at any
|
||||
/// time.
|
||||
Expn {
|
||||
mailing_list: Vec<u8>,
|
||||
},
|
||||
/// This command causes the server to send helpful information to the
|
||||
/// client. The command MAY take an argument (e.g., any command name)
|
||||
/// and return more specific information as a response.
|
||||
///
|
||||
/// SMTP servers SHOULD support HELP without arguments and MAY support it
|
||||
/// with arguments.
|
||||
///
|
||||
/// This command has no effect on the reverse-path buffer, the forward-
|
||||
/// path buffer, or the mail data buffer, and it may be issued at any
|
||||
/// time.
|
||||
Help {
|
||||
argument: Option<Vec<u8>>,
|
||||
},
|
||||
/// This command does not affect any parameters or previously entered
|
||||
/// commands. It specifies no action other than that the receiver send a
|
||||
/// "250 OK" reply.
|
||||
///
|
||||
/// If a parameter string is specified, servers SHOULD ignore it.
|
||||
///
|
||||
/// This command has no effect on the reverse-path buffer, the forward-
|
||||
/// path buffer, or the mail data buffer, and it may be issued at any
|
||||
/// time.
|
||||
Noop {
|
||||
argument: Option<Vec<u8>>,
|
||||
},
|
||||
/// This command specifies that the receiver MUST send a "221 OK" reply,
|
||||
/// and then close the transmission channel.
|
||||
///
|
||||
/// The receiver MUST NOT intentionally close the transmission channel
|
||||
/// until it receives and replies to a QUIT command (even if there was an
|
||||
/// error). The sender MUST NOT intentionally close the transmission
|
||||
/// channel until it sends a QUIT command, and it SHOULD wait until it
|
||||
/// receives the reply (even if there was an error response to a previous
|
||||
/// command). If the connection is closed prematurely due to violations
|
||||
/// of the above or system or network failure, the server MUST cancel any
|
||||
/// pending transaction, but not undo any previously completed
|
||||
/// transaction, and generally MUST act as if the command or transaction
|
||||
/// in progress had received a temporary error (i.e., a 4yz response).
|
||||
///
|
||||
/// The QUIT command may be issued at any time. Any current uncompleted
|
||||
/// mail transaction will be aborted.
|
||||
Quit,
|
||||
// Extensions
|
||||
StartTLS,
|
||||
|
@ -30,16 +93,16 @@ pub enum Command {
|
|||
impl Command {
|
||||
pub fn name(&self) -> &'static str {
|
||||
match self {
|
||||
Command::Ehlo(_) => "EHLO",
|
||||
Command::Helo(_) => "HELO",
|
||||
Command::Ehlo { .. } => "EHLO",
|
||||
Command::Helo { .. } => "HELO",
|
||||
Command::Mail { .. } => "MAIL",
|
||||
Command::Rcpt { .. } => "RCPT",
|
||||
Command::Data => "DATA",
|
||||
Command::Rset => "RSET",
|
||||
Command::Vrfy(_) => "VRFY",
|
||||
Command::Expn(_) => "EXPN",
|
||||
Command::Help(_) => "HELP",
|
||||
Command::Noop(_) => "NOOP",
|
||||
Command::Vrfy { .. } => "VRFY",
|
||||
Command::Expn { .. } => "EXPN",
|
||||
Command::Help { .. } => "HELP",
|
||||
Command::Noop { .. } => "NOOP",
|
||||
Command::Quit => "QUIT",
|
||||
// Extensions
|
||||
Command::StartTLS => "STARTTLS",
|
||||
|
@ -51,34 +114,46 @@ impl Command {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: try to derive(Debug) instead
|
||||
impl std::fmt::Debug for Command {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
use Command::*;
|
||||
|
||||
match self {
|
||||
Ehlo(data) => write!(f, "Ehlo({})", escape(data)),
|
||||
Helo(data) => write!(f, "Helo({})", escape(data)),
|
||||
Ehlo {
|
||||
fqdn_or_address_literal,
|
||||
} => write!(f, "Ehlo({})", escape(fqdn_or_address_literal)),
|
||||
Helo {
|
||||
fqdn_or_address_literal,
|
||||
} => write!(f, "Helo({})", escape(fqdn_or_address_literal)),
|
||||
Mail {
|
||||
data: path,
|
||||
params: None,
|
||||
reverse_path: path,
|
||||
parameters: None,
|
||||
} => write!(f, "Mail({})", escape(path)),
|
||||
Mail {
|
||||
data: path,
|
||||
params: Some(params),
|
||||
reverse_path: path,
|
||||
parameters: Some(params),
|
||||
} => write!(f, "Mail({}, {})", escape(path), escape(params)),
|
||||
Rcpt { data, params: None } => write!(f, "Rcpt({})", escape(data)),
|
||||
Rcpt {
|
||||
data,
|
||||
params: Some(params),
|
||||
forward_path: data,
|
||||
parameters: None,
|
||||
} => write!(f, "Rcpt({})", escape(data)),
|
||||
Rcpt {
|
||||
forward_path: data,
|
||||
parameters: Some(params),
|
||||
} => write!(f, "Rcpt({}, {})", escape(data), escape(params)),
|
||||
Data => write!(f, "Data"),
|
||||
Rset => write!(f, "Rset"),
|
||||
Vrfy(data) => write!(f, "Vrfy({})", escape(data)),
|
||||
Expn(data) => write!(f, "Expn({})", escape(data)),
|
||||
Help(None) => write!(f, "Help"),
|
||||
Help(Some(data)) => write!(f, "Help({})", escape(data)),
|
||||
Noop(None) => write!(f, "Noop"),
|
||||
Noop(Some(data)) => write!(f, "Noop({})", escape(data)),
|
||||
Vrfy { user_or_mailbox } => write!(f, "Vrfy({})", escape(user_or_mailbox)),
|
||||
Expn { mailing_list } => write!(f, "Expn({})", escape(mailing_list)),
|
||||
Help { argument: None } => write!(f, "Help"),
|
||||
Help {
|
||||
argument: Some(data),
|
||||
} => write!(f, "Help({})", escape(data)),
|
||||
Noop { argument: None } => write!(f, "Noop"),
|
||||
Noop {
|
||||
argument: Some(data),
|
||||
} => write!(f, "Noop({})", escape(data)),
|
||||
Quit => write!(f, "Quit"),
|
||||
// Extensions
|
||||
StartTLS => write!(f, "StartTLS"),
|
||||
|
|
Loading…
Reference in New Issue