jmap_mail_client/methods/
mailbox.rs1use std::collections::HashMap;
12
13use jmap_types::{Id, PatchObject, State};
14
15use super::{
16 ChangesResponse, GetResponse, MailboxSetParams, QueryChangesResponse, QueryResponse,
17 SetResponse,
18};
19
20impl super::SessionClient {
21 pub async fn mailbox_get(
26 &self,
27 ids: Option<&[Id]>,
28 properties: Option<&[&str]>,
29 ) -> Result<GetResponse<jmap_mail_types::Mailbox>, jmap_base_client::ClientError> {
30 let (api_url, account_id) = self.session_parts()?;
31 let mut args = serde_json::json!({ "accountId": account_id });
34 if let Some(id_slice) = ids {
35 args["ids"] = serde_json::to_value(id_slice).expect("Id slice Serialize is infallible");
36 }
37 if let Some(props) = properties {
38 args["properties"] = serde_json::Value::Array(
39 props.iter().copied().map(serde_json::Value::from).collect(),
40 );
41 }
42 let req = super::build_request("Mailbox/get", args, super::USING_MAIL);
43 let resp = self.call_internal(api_url, &req).await?;
44 jmap_base_client::extract_response(&resp, super::CALL_ID)
45 }
46
47 pub async fn mailbox_changes(
49 &self,
50 since_state: &State,
51 max_changes: Option<u64>,
52 ) -> Result<ChangesResponse, jmap_base_client::ClientError> {
53 if since_state.as_ref().is_empty() {
55 return Err(jmap_base_client::ClientError::InvalidArgument(
56 "mailbox_changes: since_state may not be empty".into(),
57 ));
58 }
59 let (api_url, account_id) = self.session_parts()?;
60 let mut args = serde_json::json!({
61 "accountId": account_id,
62 "sinceState": since_state,
63 });
64 if let Some(mc) = max_changes {
65 args["maxChanges"] = mc.into();
66 }
67 let req = super::build_request("Mailbox/changes", args, super::USING_MAIL);
68 let resp = self.call_internal(api_url, &req).await?;
69 jmap_base_client::extract_response(&resp, super::CALL_ID)
70 }
71
72 pub async fn mailbox_set(
83 &self,
84 create: Option<serde_json::Value>,
85 update: Option<HashMap<Id, PatchObject>>,
86 destroy: Option<Vec<Id>>,
87 params: Option<MailboxSetParams>,
88 ) -> Result<SetResponse<jmap_mail_types::Mailbox>, jmap_base_client::ClientError> {
89 let (api_url, account_id) = self.session_parts()?;
90 let mut args = serde_json::json!({
91 "accountId": account_id,
92 });
93 if let Some(p) = params {
94 if let Some(v) = p.on_destroy_remove_emails {
95 args["onDestroyRemoveEmails"] = v.into();
96 }
97 }
98 if let Some(c) = create {
99 args["create"] = c;
100 }
101 if let Some(u) = update {
102 args["update"] = serde_json::to_value(&u).map_err(|e| {
103 jmap_base_client::ClientError::InvalidArgument(format!(
104 "mailbox_set: serializing update map failed: {e}"
105 ))
106 })?;
107 }
108 if let Some(d) = destroy {
109 args["destroy"] = serde_json::to_value(&d).expect("Id Vec Serialize is infallible");
110 }
111 let req = super::build_request("Mailbox/set", args, super::USING_MAIL);
112 let resp = self.call_internal(api_url, &req).await?;
113 jmap_base_client::extract_response(&resp, super::CALL_ID)
114 }
115
116 pub async fn mailbox_query(
121 &self,
122 filter: Option<serde_json::Value>,
123 sort: Option<serde_json::Value>,
124 position: Option<u64>,
125 limit: Option<u64>,
126 ) -> Result<QueryResponse, jmap_base_client::ClientError> {
127 let (api_url, account_id) = self.session_parts()?;
128 let mut args = serde_json::json!({
129 "accountId": account_id,
130 });
131 if let Some(f) = filter {
132 args["filter"] = f;
133 }
134 if let Some(s) = sort {
135 args["sort"] = s;
136 }
137 if let Some(p) = position {
138 args["position"] = p.into();
139 }
140 if let Some(l) = limit {
141 args["limit"] = l.into();
142 }
143 let req = super::build_request("Mailbox/query", args, super::USING_MAIL);
144 let resp = self.call_internal(api_url, &req).await?;
145 jmap_base_client::extract_response(&resp, super::CALL_ID)
146 }
147
148 pub async fn mailbox_query_changes(
151 &self,
152 since_query_state: &State,
153 max_changes: Option<u64>,
154 ) -> Result<QueryChangesResponse, jmap_base_client::ClientError> {
155 if since_query_state.as_ref().is_empty() {
157 return Err(jmap_base_client::ClientError::InvalidArgument(
158 "mailbox_query_changes: since_query_state may not be empty".into(),
159 ));
160 }
161 let (api_url, account_id) = self.session_parts()?;
162 let mut args = serde_json::json!({
163 "accountId": account_id,
164 "sinceQueryState": since_query_state,
165 });
166 if let Some(mc) = max_changes {
167 args["maxChanges"] = mc.into();
168 }
169 let req = super::build_request("Mailbox/queryChanges", args, super::USING_MAIL);
170 let resp = self.call_internal(api_url, &req).await?;
171 jmap_base_client::extract_response(&resp, super::CALL_ID)
172 }
173}
174
175#[cfg(test)]
180mod tests {
181 use serde_json::json;
182
183 #[test]
208 fn mailbox_get_response_deserializes() {
209 let json = json!({
210 "accountId": "acc1",
211 "state": "s10",
212 "list": [
213 {
214 "id": "mb1",
215 "name": "Inbox",
216 "role": "inbox",
217 "sortOrder": 10,
218 "totalEmails": 42,
219 "unreadEmails": 3,
220 "totalThreads": 20,
221 "unreadThreads": 2,
222 "myRights": {
223 "mayReadItems": true,
224 "mayAddItems": true,
225 "mayRemoveItems": true,
226 "maySetSeen": true,
227 "maySetKeywords": true,
228 "mayCreateChild": true,
229 "mayRename": true,
230 "mayDelete": false,
231 "maySubmit": false
232 },
233 "isSubscribed": true
234 }
235 ],
236 "notFound": []
237 });
238 use super::super::GetResponse;
239 let resp: GetResponse<jmap_mail_types::Mailbox> =
240 serde_json::from_value(json).expect("must deserialize Mailbox GetResponse");
241 assert_eq!(resp.list.len(), 1);
242 assert_eq!(resp.list[0].name, "Inbox");
243 }
244}