1use alloc::{
4 string::{String, ToString},
5 vec::Vec,
6};
7use core::fmt;
8
9use serde::{Deserialize, Deserializer, Serialize, Serializer};
10
11#[derive(Clone, Debug, Default, Serialize, Deserialize)]
13#[serde(rename_all = "camelCase")]
14pub struct JmapMailbox {
15 pub id: Option<String>,
16 pub name: Option<String>,
17 pub parent_id: Option<String>,
19 pub role: Option<JmapMailboxRole>,
20 #[serde(default)]
21 pub sort_order: u32,
22 #[serde(default)]
23 pub total_emails: u32,
24 #[serde(default)]
25 pub unread_emails: u32,
26 #[serde(default)]
27 pub total_threads: u32,
28 #[serde(default)]
29 pub unread_threads: u32,
30 #[serde(default)]
31 pub my_rights: JmapMailboxRights,
32 #[serde(default)]
33 pub is_subscribed: bool,
34}
35
36#[derive(Clone, Debug, Default, Serialize)]
39#[serde(rename_all = "camelCase")]
40pub struct JmapMailboxCreate {
41 #[serde(skip_serializing_if = "Option::is_none")]
42 pub name: Option<String>,
43 #[serde(skip_serializing_if = "Option::is_none")]
44 pub parent_id: Option<String>,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 pub role: Option<JmapMailboxRole>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub sort_order: Option<u32>,
49 #[serde(skip_serializing_if = "Option::is_none")]
50 pub is_subscribed: Option<bool>,
51}
52
53#[derive(Clone, Debug, Default, Serialize)]
56#[serde(rename_all = "camelCase")]
57pub struct JmapMailboxUpdate {
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub name: Option<String>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub parent_id: Option<String>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub role: Option<JmapMailboxRole>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 pub sort_order: Option<u32>,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub is_subscribed: Option<bool>,
68}
69
70#[derive(Clone, Debug, Default, Serialize, Deserialize)]
72#[serde(rename_all = "camelCase")]
73pub struct JmapMailboxRights {
74 pub may_read_items: bool,
76 pub may_add_items: bool,
78 pub may_remove_items: bool,
80 pub may_set_seen: bool,
82 pub may_set_keywords: bool,
84 pub may_create_child: bool,
86 pub may_rename: bool,
88 pub may_delete: bool,
90 pub may_submit: bool,
92}
93
94#[derive(Clone, Debug, PartialEq, Eq)]
97pub enum JmapMailboxRole {
98 Inbox,
100 Archive,
102 Drafts,
104 Flagged,
106 Important,
108 Junk,
110 Sent,
112 Subscribed,
114 Trash,
116 Other(String),
118}
119
120impl fmt::Display for JmapMailboxRole {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 f.write_str(match self {
123 Self::Inbox => "inbox",
124 Self::Archive => "archive",
125 Self::Drafts => "drafts",
126 Self::Flagged => "flagged",
127 Self::Important => "important",
128 Self::Junk => "junk",
129 Self::Sent => "sent",
130 Self::Subscribed => "subscribed",
131 Self::Trash => "trash",
132 Self::Other(s) => s.as_str(),
133 })
134 }
135}
136
137impl Serialize for JmapMailboxRole {
138 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
139 s.serialize_str(&self.to_string())
140 }
141}
142
143impl<'de> Deserialize<'de> for JmapMailboxRole {
144 fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
145 let s = String::deserialize(d)?;
146 Ok(match s.as_str() {
147 "inbox" => Self::Inbox,
148 "archive" => Self::Archive,
149 "drafts" => Self::Drafts,
150 "flagged" => Self::Flagged,
151 "important" => Self::Important,
152 "junk" => Self::Junk,
153 "sent" => Self::Sent,
154 "subscribed" => Self::Subscribed,
155 "trash" => Self::Trash,
156 _ => Self::Other(s),
157 })
158 }
159}
160
161#[derive(Clone, Debug, Serialize)]
163#[serde(rename_all = "camelCase")]
164pub enum JmapMailboxProperty {
165 Id,
166 Name,
167 ParentId,
168 Role,
169 SortOrder,
170 TotalEmails,
171 UnreadEmails,
172 TotalThreads,
173 UnreadThreads,
174 MyRights,
175 IsSubscribed,
176}
177
178#[derive(Clone, Debug, Serialize)]
180#[serde(rename_all = "camelCase")]
181pub enum JmapMailboxSortProperty {
182 Name,
183 SortOrder,
184 ParentId,
185}
186
187#[derive(Clone, Debug, Serialize)]
189#[serde(rename_all = "camelCase")]
190pub struct JmapMailboxSortComparator {
191 pub property: JmapMailboxSortProperty,
192 #[serde(skip_serializing_if = "Option::is_none")]
193 pub is_ascending: Option<bool>,
194}
195
196#[derive(Clone, Debug, Default, Serialize, Deserialize)]
198#[serde(rename_all = "camelCase")]
199pub struct JmapMailboxFilter {
200 #[serde(skip_serializing_if = "Option::is_none")]
202 pub parent_id: Option<String>,
203
204 #[serde(skip_serializing_if = "Option::is_none")]
206 pub role: Option<JmapMailboxRole>,
207
208 #[serde(skip_serializing_if = "Option::is_none")]
210 pub name: Option<String>,
211
212 #[serde(skip_serializing_if = "Option::is_none")]
214 pub is_subscribed: Option<bool>,
215
216 #[serde(skip_serializing_if = "Option::is_none")]
218 pub has_any_role: Option<bool>,
219}
220
221#[derive(Clone, Debug, Deserialize)]
226#[serde(tag = "type", rename_all = "camelCase")]
227pub enum JmapMailboxSetItemError {
228 MailboxHasChild {
230 description: Option<String>,
231 },
232 MailboxHasEmail {
234 description: Option<String>,
235 },
236 NotFound {
237 description: Option<String>,
238 },
239 InvalidPatch {
240 description: Option<String>,
241 },
242 WillDestroy {
243 description: Option<String>,
244 },
245 InvalidProperties {
246 description: Option<String>,
247 #[serde(default)]
248 properties: Vec<String>,
249 },
250 Singleton {
251 description: Option<String>,
252 },
253 #[serde(other)]
254 Unknown,
255}