io_jmap/rfc8621/email.rs
1//! JMAP for Mail: Email (RFC 8621 §4).
2
3use alloc::{collections::BTreeMap, string::String, vec::Vec};
4
5use serde::{Deserialize, Serialize};
6
7pub mod changes;
8pub mod copy;
9pub mod get;
10pub mod import;
11pub mod parse;
12pub mod query;
13pub mod set;
14
15/// The email has been read.
16pub const JMAP_KEYWORD_SEEN: &str = "$seen";
17
18/// The email has been flagged for follow-up.
19pub const JMAP_KEYWORD_FLAGGED: &str = "$flagged";
20
21/// The email has been replied to.
22pub const JMAP_KEYWORD_ANSWERED: &str = "$answered";
23
24/// The email is a draft.
25pub const JMAP_KEYWORD_DRAFT: &str = "$draft";
26
27/// A JMAP Email object (RFC 8621 §4.1).
28#[derive(Clone, Debug, Default, Serialize, Deserialize)]
29#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
30#[serde(rename_all = "camelCase")]
31pub struct JmapEmail {
32 /// The server-assigned email id.
33 pub id: Option<String>,
34 /// Blob ID for the raw RFC 5322 message.
35 pub blob_id: Option<String>,
36 /// The id of the thread the email belongs to.
37 pub thread_id: Option<String>,
38 /// `{ mailbox-id -> true }` for each mailbox containing the email.
39 pub mailbox_ids: Option<BTreeMap<String, bool>>,
40 /// `{ keyword -> true }`. Standard: `$seen`, `$flagged`, `$answered`,
41 /// `$draft`.
42 pub keywords: Option<BTreeMap<String, bool>>,
43 /// Size of the raw RFC 5322 message, in bytes.
44 pub size: Option<u64>,
45 /// RFC 3339 receive time.
46 pub received_at: Option<String>,
47 /// The `Message-ID` header values.
48 pub message_id: Option<Vec<String>>,
49 /// The `In-Reply-To` header values.
50 pub in_reply_to: Option<Vec<String>>,
51 /// The `References` header values.
52 pub references: Option<Vec<String>>,
53 /// The `Sender` header addresses.
54 pub sender: Option<Vec<JmapEmailAddress>>,
55 /// The `From` header addresses.
56 pub from: Option<Vec<JmapEmailAddress>>,
57 /// The `To` header addresses.
58 pub to: Option<Vec<JmapEmailAddress>>,
59 /// The `Cc` header addresses.
60 pub cc: Option<Vec<JmapEmailAddress>>,
61 /// The `Bcc` header addresses.
62 pub bcc: Option<Vec<JmapEmailAddress>>,
63 /// The `Reply-To` header addresses.
64 pub reply_to: Option<Vec<JmapEmailAddress>>,
65 /// The `Subject` header value.
66 pub subject: Option<String>,
67 /// `Date` header as an RFC 3339 string.
68 pub sent_at: Option<String>,
69 /// The full MIME structure of the message.
70 pub body_structure: Option<JmapEmailBodyPart>,
71 /// `{ part-id -> body }` for text parts.
72 pub body_values: Option<BTreeMap<String, JmapEmailBodyValue>>,
73 /// The text/plain parts to display as the message body.
74 pub text_body: Option<Vec<JmapEmailBodyPart>>,
75 /// The text/html parts to display as the message body.
76 pub html_body: Option<Vec<JmapEmailBodyPart>>,
77 /// The parts to display as attachments.
78 pub attachments: Option<Vec<JmapEmailBodyPart>>,
79 /// Whether any part is an attachment.
80 pub has_attachment: Option<bool>,
81 /// Short plaintext preview (up to 256 chars).
82 pub preview: Option<String>,
83 /// Raw headers in order of appearance.
84 pub headers: Option<Vec<JmapEmailHeader>>,
85}
86
87/// An email address (name + email pair).
88#[derive(Clone, Debug, Serialize, Deserialize)]
89#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
90#[serde(rename_all = "camelCase")]
91pub struct JmapEmailAddress {
92 /// The display name, when present.
93 pub name: Option<String>,
94 /// The address itself (local@domain).
95 pub email: String,
96}
97
98/// A raw email header name-value pair.
99#[derive(Clone, Debug, Serialize, Deserialize)]
100#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
101#[serde(rename_all = "camelCase")]
102pub struct JmapEmailHeader {
103 /// Field name, without trailing colon.
104 pub name: String,
105 /// Raw value, with leading whitespace preserved.
106 pub value: String,
107}
108
109/// A MIME body part descriptor.
110#[derive(Clone, Debug, Default, Serialize, Deserialize)]
111#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
112#[serde(rename_all = "camelCase")]
113pub struct JmapEmailBodyPart {
114 /// Part id, scoped to the message.
115 pub part_id: Option<String>,
116 /// Blob id to download the decoded part content.
117 pub blob_id: Option<String>,
118 /// Size of the decoded part content, in bytes.
119 pub size: Option<u64>,
120 /// Filename from `Content-Disposition` or `Content-Type`.
121 pub name: Option<String>,
122 /// The `Content-Type` media type.
123 pub r#type: Option<String>,
124 /// The `Content-Type` charset parameter.
125 pub charset: Option<String>,
126 /// `inline` or `attachment`.
127 pub disposition: Option<String>,
128 /// The `Content-Id` value, without angle brackets.
129 pub cid: Option<String>,
130 /// The `Content-Language` values.
131 pub language: Option<Vec<String>>,
132 /// The `Content-Location` value.
133 pub location: Option<String>,
134 /// Sub-parts (multipart only).
135 pub sub_parts: Option<Vec<JmapEmailBodyPart>>,
136 /// Raw headers of the part.
137 pub headers: Option<Vec<JmapEmailHeader>>,
138}
139
140/// The text content of a body part.
141#[derive(Clone, Debug, Serialize, Deserialize)]
142#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
143#[serde(rename_all = "camelCase")]
144pub struct JmapEmailBodyValue {
145 /// The decoded text content.
146 pub value: String,
147 /// Charset or encoding problem during decode.
148 pub is_encoding_problem: bool,
149 /// Whether the value was truncated.
150 pub is_truncated: bool,
151}
152
153/// [`JmapEmail`] properties requestable in `Email/get` (RFC 8621 §4.1).
154#[derive(Clone, Debug, Serialize)]
155#[serde(rename_all = "camelCase")]
156pub enum JmapEmailProperty {
157 /// The `id` property.
158 Id,
159 /// The `blobId` property.
160 BlobId,
161 /// The `threadId` property.
162 ThreadId,
163 /// The `mailboxIds` property.
164 MailboxIds,
165 /// The `keywords` property.
166 Keywords,
167 /// The `size` property.
168 Size,
169 /// The `receivedAt` property.
170 ReceivedAt,
171 /// The `messageId` property.
172 MessageId,
173 /// The `inReplyTo` property.
174 InReplyTo,
175 /// The `references` property.
176 References,
177 /// The `sender` property.
178 Sender,
179 /// The `from` property.
180 From,
181 /// The `to` property.
182 To,
183 /// The `cc` property.
184 Cc,
185 /// The `bcc` property.
186 Bcc,
187 /// The `replyTo` property.
188 ReplyTo,
189 /// The `subject` property.
190 Subject,
191 /// The `sentAt` property.
192 SentAt,
193 /// The `bodyStructure` property.
194 BodyStructure,
195 /// The `bodyValues` property.
196 BodyValues,
197 /// The `textBody` property.
198 TextBody,
199 /// The `htmlBody` property.
200 HtmlBody,
201 /// The `attachments` property.
202 Attachments,
203 /// The `hasAttachment` property.
204 HasAttachment,
205 /// The `preview` property.
206 Preview,
207 /// The `headers` property.
208 Headers,
209}