nylas_types/
attachment.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
24pub struct Attachment {
25 pub id: String,
27
28 #[serde(skip_serializing_if = "Option::is_none")]
30 pub grant_id: Option<String>,
31
32 #[serde(skip_serializing_if = "Option::is_none")]
34 pub filename: Option<String>,
35
36 #[serde(skip_serializing_if = "Option::is_none")]
38 pub content_type: Option<String>,
39
40 #[serde(skip_serializing_if = "Option::is_none")]
42 pub size: Option<u64>,
43
44 #[serde(skip_serializing_if = "Option::is_none")]
46 pub content_id: Option<String>,
47
48 #[serde(skip_serializing_if = "Option::is_none")]
50 pub is_inline: Option<bool>,
51}
52
53impl Attachment {
54 pub fn builder() -> AttachmentBuilder {
56 AttachmentBuilder::default()
57 }
58}
59
60#[derive(Debug, Clone, Default)]
62pub struct AttachmentBuilder {
63 id: Option<String>,
64 grant_id: Option<String>,
65 filename: Option<String>,
66 content_type: Option<String>,
67 size: Option<u64>,
68 content_id: Option<String>,
69 is_inline: Option<bool>,
70}
71
72impl AttachmentBuilder {
73 pub fn id(mut self, id: impl Into<String>) -> Self {
75 self.id = Some(id.into());
76 self
77 }
78
79 pub fn grant_id(mut self, grant_id: impl Into<String>) -> Self {
81 self.grant_id = Some(grant_id.into());
82 self
83 }
84
85 pub fn filename(mut self, filename: impl Into<String>) -> Self {
87 self.filename = Some(filename.into());
88 self
89 }
90
91 pub fn content_type(mut self, content_type: impl Into<String>) -> Self {
93 self.content_type = Some(content_type.into());
94 self
95 }
96
97 pub fn size(mut self, size: u64) -> Self {
99 self.size = Some(size);
100 self
101 }
102
103 pub fn content_id(mut self, content_id: impl Into<String>) -> Self {
105 self.content_id = Some(content_id.into());
106 self
107 }
108
109 pub fn is_inline(mut self, is_inline: bool) -> Self {
111 self.is_inline = Some(is_inline);
112 self
113 }
114
115 pub fn build(self) -> Attachment {
121 Attachment {
122 id: self.id.expect("Attachment ID is required"),
123 grant_id: self.grant_id,
124 filename: self.filename,
125 content_type: self.content_type,
126 size: self.size,
127 content_id: self.content_id,
128 is_inline: self.is_inline,
129 }
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_attachment_creation() {
139 let attachment = Attachment {
140 id: "att_123".to_string(),
141 grant_id: Some("grant_123".to_string()),
142 filename: Some("document.pdf".to_string()),
143 content_type: Some("application/pdf".to_string()),
144 size: Some(12345),
145 content_id: None,
146 is_inline: Some(false),
147 };
148
149 assert_eq!(attachment.id, "att_123");
150 assert_eq!(attachment.filename, Some("document.pdf".to_string()));
151 assert_eq!(attachment.size, Some(12345));
152 }
153
154 #[test]
155 fn test_attachment_builder() {
156 let attachment = Attachment::builder()
157 .id("att_123")
158 .filename("test.pdf")
159 .content_type("application/pdf")
160 .size(1024)
161 .is_inline(false)
162 .build();
163
164 assert_eq!(attachment.id, "att_123");
165 assert_eq!(attachment.filename, Some("test.pdf".to_string()));
166 assert_eq!(attachment.content_type, Some("application/pdf".to_string()));
167 assert_eq!(attachment.size, Some(1024));
168 assert_eq!(attachment.is_inline, Some(false));
169 }
170
171 #[test]
172 fn test_attachment_inline() {
173 let attachment = Attachment::builder()
174 .id("att_inline")
175 .filename("image.png")
176 .content_type("image/png")
177 .content_id("img001")
178 .is_inline(true)
179 .build();
180
181 assert_eq!(attachment.content_id, Some("img001".to_string()));
182 assert_eq!(attachment.is_inline, Some(true));
183 }
184
185 #[test]
186 fn test_attachment_serialization() {
187 let attachment = Attachment {
188 id: "att_123".to_string(),
189 grant_id: Some("grant_123".to_string()),
190 filename: Some("test.pdf".to_string()),
191 content_type: Some("application/pdf".to_string()),
192 size: Some(5000),
193 content_id: None,
194 is_inline: Some(false),
195 };
196
197 let json = serde_json::to_string(&attachment).unwrap();
198 assert!(json.contains("att_123"));
199 assert!(json.contains("test.pdf"));
200 assert!(json.contains("5000"));
201
202 let deserialized: Attachment = serde_json::from_str(&json).unwrap();
203 assert_eq!(deserialized, attachment);
204 }
205
206 #[test]
207 fn test_attachment_minimal() {
208 let attachment = Attachment::builder().id("att_minimal").build();
209
210 assert_eq!(attachment.id, "att_minimal");
211 assert_eq!(attachment.filename, None);
212 assert_eq!(attachment.size, None);
213 }
214
215 #[test]
216 #[should_panic(expected = "Attachment ID is required")]
217 fn test_attachment_builder_without_id() {
218 Attachment::builder().filename("test.pdf").build();
219 }
220}