1#![allow(clippy::field_reassign_with_default)]
2use crate::ClientError;
3use crate::{ClientResult, Response};
4
5#[async_trait::async_trait]
6pub trait MailOps {
7 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 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}