sendgrid_api/
traits.rs

1#![allow(clippy::field_reassign_with_default)]
2use crate::ClientError;
3use crate::{ClientResult, Response};
4
5#[async_trait::async_trait]
6pub trait MailOps {
7    /// Send a plain text email.
8    ///
9    /// This is a nicer experience than using `post`.
10    async fn send_plain_text(
11        &self,
12        subject: &str,
13        message: &str,
14        to: &[String],
15        cc: &[String],
16        bcc: &[String],
17        from: &str,
18    ) -> ClientResult<Response<()>>;
19}
20
21#[async_trait::async_trait]
22impl MailOps for crate::mail_send::MailSend {
23    /// Send a plain text email.
24    ///
25    /// This is a nicer experience than using `post`.
26    async fn send_plain_text(
27        &self,
28        subject: &str,
29        message: &str,
30        tos: &[String],
31        ccs: &[String],
32        bccs: &[String],
33        from: &str,
34    ) -> ClientResult<Response<()>> {
35        let mut mail = crate::types::PostMailSendRequest {
36            subject: subject.to_string(),
37            from: crate::types::FromEmailObject {
38                email: from.to_string(),
39                name: String::new(),
40            },
41            content: vec![crate::types::Content {
42                value: message.to_string(),
43                type_: "text/plain".to_string(),
44            }],
45            ..Default::default()
46        };
47        let mut p = crate::types::Personalizations {
48            from: Some(mail.from.clone()),
49            ..Default::default()
50        };
51        for to in tos {
52            p.to.push(crate::types::ReplyTo {
53                email: to.to_string(),
54                name: String::new(),
55            });
56        }
57        for cc in ccs {
58            p.cc.push(crate::types::CcBccEmailObject {
59                email: cc.to_string(),
60                name: String::new(),
61            });
62        }
63        for bcc in bccs {
64            p.bcc.push(crate::types::CcBccEmailObject {
65                email: bcc.to_string(),
66                name: String::new(),
67            });
68        }
69        mail.personalizations = vec![p];
70
71        let url = self.client.url("/mail/send", None);
72        let resp = self
73            .client
74            .request_raw(
75                reqwest::Method::POST,
76                &url,
77                crate::Message {
78                    body: Some(reqwest::Body::from(serde_json::to_vec(&mail).unwrap())),
79                    content_type: None,
80                },
81            )
82            .await?;
83
84        match resp.status() {
85            http::StatusCode::ACCEPTED => Ok(Response::new(
86                http::StatusCode::ACCEPTED,
87                resp.headers().clone(),
88                (),
89            )),
90            s => Err(ClientError::HttpError {
91                status: s,
92                headers: resp.headers().clone(),
93                error: "Posting to /mail/send".to_string(),
94            }),
95        }
96    }
97}