Skip to main content

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}