1use rusmes_proto::MailAddress;
4use std::fmt;
5
6#[derive(Debug, Clone, PartialEq)]
8pub enum SmtpCommand {
9 Helo(String),
11 Ehlo(String),
13 Mail {
15 from: MailAddress,
16 params: Vec<MailParam>,
17 },
18 Rcpt {
20 to: MailAddress,
21 params: Vec<MailParam>,
22 },
23 Data,
25 Bdat { chunk_size: usize, last: bool },
27 Rset,
29 Noop,
31 Quit,
33 Vrfy(String),
35 Expn(String),
37 Help(Option<String>),
39 StartTls,
41 Auth {
43 mechanism: String,
44 initial_response: Option<String>,
45 },
46}
47
48impl fmt::Display for SmtpCommand {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 match self {
51 SmtpCommand::Helo(domain) => write!(f, "HELO {}", domain),
52 SmtpCommand::Ehlo(domain) => write!(f, "EHLO {}", domain),
53 SmtpCommand::Mail { from, .. } => write!(f, "MAIL FROM:<{}>", from),
54 SmtpCommand::Rcpt { to, .. } => write!(f, "RCPT TO:<{}>", to),
55 SmtpCommand::Data => write!(f, "DATA"),
56 SmtpCommand::Bdat { chunk_size, last } => {
57 if *last {
58 write!(f, "BDAT {} LAST", chunk_size)
59 } else {
60 write!(f, "BDAT {}", chunk_size)
61 }
62 }
63 SmtpCommand::Rset => write!(f, "RSET"),
64 SmtpCommand::Noop => write!(f, "NOOP"),
65 SmtpCommand::Quit => write!(f, "QUIT"),
66 SmtpCommand::Vrfy(addr) => write!(f, "VRFY {}", addr),
67 SmtpCommand::Expn(list) => write!(f, "EXPN {}", list),
68 SmtpCommand::Help(topic) => {
69 if let Some(t) = topic {
70 write!(f, "HELP {}", t)
71 } else {
72 write!(f, "HELP")
73 }
74 }
75 SmtpCommand::StartTls => write!(f, "STARTTLS"),
76 SmtpCommand::Auth { mechanism, .. } => write!(f, "AUTH {}", mechanism),
77 }
78 }
79}
80
81#[derive(Debug, Clone, PartialEq)]
83pub struct MailParam {
84 pub keyword: String,
85 pub value: Option<String>,
86}
87
88impl MailParam {
89 pub fn new(keyword: impl Into<String>, value: Option<String>) -> Self {
91 Self {
92 keyword: keyword.into(),
93 value,
94 }
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101
102 #[test]
103 fn test_command_display() {
104 let cmd = SmtpCommand::Helo("example.com".to_string());
105 assert_eq!(cmd.to_string(), "HELO example.com");
106
107 let cmd = SmtpCommand::Data;
108 assert_eq!(cmd.to_string(), "DATA");
109
110 let cmd = SmtpCommand::Quit;
111 assert_eq!(cmd.to_string(), "QUIT");
112 }
113}