mail_send/smtp/
envelope.rs1use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};
12
13use crate::SmtpClient;
14
15use super::{message::Parameters, AssertReply};
16
17impl<T: AsyncRead + AsyncWrite + Unpin> SmtpClient<T> {
18 pub async fn mail_from(&mut self, addr: &str, params: &Parameters<'_>) -> crate::Result<()> {
20 self.cmd(format!("MAIL FROM:<{addr}>{params}\r\n").as_bytes())
21 .await?
22 .assert_positive_completion()
23 }
24
25 pub async fn rcpt_to(&mut self, addr: &str, params: &Parameters<'_>) -> crate::Result<()> {
27 self.cmd(format!("RCPT TO:<{addr}>{params}\r\n").as_bytes())
28 .await?
29 .assert_positive_completion()
30 }
31
32 pub async fn data(&mut self, message: impl AsRef<[u8]>) -> crate::Result<()> {
34 self.cmd(b"DATA\r\n").await?.assert_code(354)?;
35 tokio::time::timeout(self.timeout, async {
36 self.write_message(message.as_ref()).await?;
38 self.read().await
39 })
40 .await
41 .map_err(|_| crate::Error::Timeout)??
42 .assert_positive_completion()
43 }
44
45 pub async fn bdat(&mut self, message: impl AsRef<[u8]>) -> crate::Result<()> {
47 let message = message.as_ref();
48 tokio::time::timeout(self.timeout, async {
49 self.stream
50 .write_all(format!("BDAT {} LAST\r\n", message.len()).as_bytes())
51 .await?;
52 self.stream.write_all(message).await?;
53 self.stream.flush().await?;
54 self.read().await
55 })
56 .await
57 .map_err(|_| crate::Error::Timeout)??
58 .assert_positive_completion()
59 }
60
61 pub async fn rset(&mut self) -> crate::Result<()> {
63 self.cmd(b"RSET\r\n").await?.assert_positive_completion()
64 }
65
66 pub async fn noop(&mut self) -> crate::Result<()> {
68 self.cmd(b"NOOP\r\n").await?.assert_positive_completion()
69 }
70
71 pub async fn quit(mut self) -> crate::Result<()> {
73 self.cmd(b"QUIT\r\n").await?.assert_positive_completion()
74 }
75}