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