1use serde::{Deserialize, Serialize};
6
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
9#[serde(rename_all = "PascalCase")]
10pub enum BodyType {
11 Text,
13 HTML,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct EmailAddress {
20 pub address: String,
22 #[serde(skip_serializing_if = "Option::is_none")]
24 pub name: Option<String>,
25}
26
27impl EmailAddress {
28 pub fn new(address: impl Into<String>) -> Self {
30 Self {
31 address: address.into(),
32 name: None,
33 }
34 }
35 pub fn with_name(mut self, name: impl Into<String>) -> Self {
37 self.name = Some(name.into());
38 self
39 }
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct Recipient {
45 pub email_address: EmailAddress,
47}
48
49impl Recipient {
50 pub fn new(address: impl Into<String>) -> Self {
52 Self {
53 email_address: EmailAddress::new(address),
54 }
55 }
56 pub fn with_name(address: impl Into<String>, name: impl Into<String>) -> Self {
58 Self {
59 email_address: EmailAddress::new(address).with_name(name),
60 }
61 }
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
66pub struct MessageBody {
67 #[serde(rename = "contentType")]
69 pub content_type: BodyType,
70 pub content: String,
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize)]
76pub struct FileAttachment {
77 #[serde(rename = "@odata.type")]
79 pub odata_type: String,
80 pub name: String,
82 #[serde(rename = "contentType")]
84 pub content_type: String,
85 #[serde(rename = "contentBytes")]
87 pub content_bytes: String,
88}
89
90impl FileAttachment {
91 pub fn new(
93 name: impl Into<String>,
94 content_type: impl Into<String>,
95 content_bytes_base64: impl Into<String>,
96 ) -> Self {
97 Self {
98 odata_type: "#microsoft.graph.fileAttachment".to_string(),
99 name: name.into(),
100 content_type: content_type.into(),
101 content_bytes: content_bytes_base64.into(),
102 }
103 }
104}
105
106#[allow(dead_code)]
108#[derive(Debug, Clone, Serialize, Deserialize)]
109#[serde(tag = "@odata.type", rename_all = "camelCase")]
110pub enum Attachment {
111 #[serde(rename = "#microsoft.graph.fileAttachment")]
113 File(FileAttachment),
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct Message {
119 pub subject: String,
121 pub body: MessageBody,
123 #[serde(rename = "toRecipients")]
125 pub to_recipients: Vec<Recipient>,
126 #[serde(rename = "ccRecipients", skip_serializing_if = "Vec::is_empty")]
128 pub cc_recipients: Vec<Recipient>,
129 #[serde(rename = "bccRecipients", skip_serializing_if = "Vec::is_empty")]
131 pub bcc_recipients: Vec<Recipient>,
132 #[serde(skip_serializing_if = "Option::is_none")]
134 pub attachments: Option<Vec<FileAttachment>>,
135}
136
137impl Default for Message {
138 fn default() -> Self {
139 Self {
140 subject: String::new(),
141 body: MessageBody {
142 content_type: BodyType::Text,
143 content: String::new(),
144 },
145 to_recipients: vec![],
146 cc_recipients: vec![],
147 bcc_recipients: vec![],
148 attachments: None,
149 }
150 }
151}
152
153#[derive(Debug, Clone, Serialize, Deserialize)]
155pub struct SendMailRequest {
156 pub message: Message,
158 #[serde(rename = "saveToSentItems", skip_serializing_if = "Option::is_none")]
160 pub save_to_sent_items: Option<bool>,
161}
162
163impl SendMailRequest {
164 pub fn new(message: Message) -> Self {
166 Self {
167 message,
168 save_to_sent_items: Some(true),
169 }
170 }
171 pub fn save_to_sent_items(mut self, save: bool) -> Self {
173 self.save_to_sent_items = Some(save);
174 self
175 }
176}