1use crate::Client;
2use crate::error::Error;
3use crate::mailbox::Mailbox;
4use bytes::Bytes;
5use futures::Stream;
6use jiff::Timestamp;
7use serde::Deserialize;
8
9#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub(crate) struct MessagePreviewData {
12 #[serde(rename = "_id")]
13 id: String,
14 #[serde(with = "jiff::fmt::serde::timestamp::second::required")]
15 received_at: Timestamp,
16 from: String,
17 subject: String,
18 body_preview: String,
19 attachments_count: u32,
20}
21
22#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
24#[serde(rename_all = "camelCase")]
25pub(crate) struct MessageData {
26 #[serde(flatten)]
27 preview: MessagePreviewData,
28
29 user_id: String,
30 mailbox: String,
31 body_html: String,
32 attachments: Vec<AttachmentMetadata>,
33 created_at: Timestamp,
34}
35
36#[derive(Clone, Eq, PartialEq, Hash, Debug, Deserialize)]
38pub struct AttachmentMetadata {
39 #[serde(rename = "_id")]
40 id: u32,
41 filename: String,
42 size: u64,
43 #[serde(rename = "mimetype")]
44 mime_type: String,
45 cid: String,
46}
47
48impl AttachmentMetadata {
49 pub fn id(&self) -> u32 {
51 self.id
52 }
53
54 pub fn filename(&self) -> &str {
56 &self.filename
57 }
58
59 pub fn size(&self) -> u64 {
61 self.size
62 }
63
64 pub fn mime_type(&self) -> &str {
66 &self.mime_type
67 }
68
69 pub fn cid(&self) -> &str {
71 &self.cid
72 }
73}
74
75pub struct MessagePreview<'a> {
77 client: &'a Client,
78 mailbox: &'a Mailbox<'a>,
79 data: MessagePreviewData,
80}
81
82impl<'a> MessagePreview<'a> {
83 pub(crate) fn new(
84 client: &'a Client,
85 mailbox: &'a Mailbox<'a>,
86 data: MessagePreviewData,
87 ) -> Self {
88 Self {
89 client,
90 mailbox,
91 data,
92 }
93 }
94
95 pub fn id(&self) -> &str {
97 &self.data.id
98 }
99
100 pub fn received_at(&self) -> Timestamp {
102 self.data.received_at
103 }
104
105 pub fn from(&self) -> &str {
107 &self.data.from
108 }
109
110 pub fn subject(&self) -> &str {
112 &self.data.subject
113 }
114
115 pub fn body_preview(&self) -> &str {
117 &self.data.body_preview
118 }
119
120 pub fn attachments_count(&self) -> u32 {
122 self.data.attachments_count
123 }
124
125 pub async fn to_message(self) -> Result<Message<'a>, Error> {
130 let data = self
131 .client
132 .get_message(self.mailbox.token(), &self.data.id)
133 .await?;
134 Ok(Message::new(self.client, self.mailbox, data))
135 }
136}
137
138pub struct Message<'a> {
140 client: &'a Client,
141 mailbox: &'a Mailbox<'a>,
142 data: MessageData,
143}
144
145impl<'a> Message<'a> {
146 fn new(client: &'a Client, mailbox: &'a Mailbox<'a>, data: MessageData) -> Self {
147 Self {
148 client,
149 mailbox,
150 data,
151 }
152 }
153
154 pub fn id(&self) -> &str {
156 &self.data.preview.id
157 }
158
159 pub fn received_at(&self) -> Timestamp {
161 self.data.preview.received_at
162 }
163
164 pub fn from(&self) -> &str {
166 &self.data.preview.from
167 }
168
169 pub fn subject(&self) -> &str {
171 &self.data.preview.subject
172 }
173
174 pub fn body_preview(&self) -> &str {
176 &self.data.preview.body_preview
177 }
178
179 pub fn attachments_count(&self) -> u32 {
181 self.data.preview.attachments_count
182 }
183
184 pub fn body_html(&self) -> &str {
186 &self.data.body_html
187 }
188
189 pub fn attachments(&self) -> &[AttachmentMetadata] {
191 &self.data.attachments
192 }
193
194 pub fn created_at(&self) -> Timestamp {
196 self.data.created_at
197 }
198
199 pub async fn get_attachment(
201 &self,
202 id: u32,
203 ) -> Result<impl Stream<Item = Result<Bytes, Error>>, Error> {
204 self.client
205 .get_attachment(self.mailbox.token(), &self.data.preview.id, id)
206 .await
207 }
208}