1use crate::{
13 blob::copy::CopyBlobRequest,
14 client::Client,
15 email::{
16 import::EmailImportRequest, parse::EmailParseRequest,
17 search_snippet::SearchSnippetGetRequest, Email,
18 },
19 email_submission::EmailSubmission,
20 identity::Identity,
21 mailbox::Mailbox,
22 principal::Principal,
23 push_subscription::PushSubscription,
24 sieve::{validate::SieveScriptValidateRequest, SieveScript},
25 thread::Thread,
26 vacation_response::VacationResponse,
27 Error, Method, Set, URI,
28};
29use ahash::AHashMap;
30use serde::{de::DeserializeOwned, Serialize};
31
32use super::{
33 changes::ChangesRequest,
34 copy::CopyRequest,
35 get::GetRequest,
36 query::QueryRequest,
37 query_changes::QueryChangesRequest,
38 response::{Response, SingleMethodResponse, TaggedMethodResponse},
39 set::SetRequest,
40 RequestParams,
41};
42
43#[derive(Serialize)]
44pub struct Request<'x> {
45 #[serde(skip)]
46 client: &'x Client,
47 #[serde(skip)]
48 account_id: String,
49
50 pub using: Vec<URI>,
51
52 #[serde(rename = "methodCalls")]
53 pub method_calls: Vec<(Method, Arguments, String)>,
54
55 #[serde(rename = "createdIds")]
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub created_ids: Option<AHashMap<String, String>>,
58}
59
60#[derive(Debug, Clone, Serialize)]
61pub struct ResultReference {
62 #[serde(rename = "resultOf")]
63 result_of: String,
64 name: Method,
65 path: String,
66}
67
68#[derive(Debug, Clone, Serialize)]
69#[serde(untagged)]
70pub enum Arguments {
71 Changes(ChangesRequest),
72 PushGet(GetRequest<PushSubscription<Set>>),
73 PushSet(SetRequest<PushSubscription<Set>>),
74 BlobCopy(CopyBlobRequest),
75 MailboxGet(GetRequest<Mailbox<Set>>),
76 MailboxQuery(QueryRequest<Mailbox<Set>>),
77 MailboxQueryChanges(QueryChangesRequest<Mailbox<Set>>),
78 MailboxSet(SetRequest<Mailbox<Set>>),
79 ThreadGet(GetRequest<Thread>),
80 EmailGet(GetRequest<Email<Set>>),
81 EmailQuery(QueryRequest<Email<Set>>),
82 EmailQueryChanges(QueryChangesRequest<Email<Set>>),
83 EmailSet(SetRequest<Email<Set>>),
84 EmailCopy(CopyRequest<Email<Set>>),
85 EmailImport(EmailImportRequest),
86 EmailParse(EmailParseRequest),
87 SearchSnippetGet(SearchSnippetGetRequest),
88 IdentityGet(GetRequest<Identity<Set>>),
89 IdentitySet(SetRequest<Identity<Set>>),
90 EmailSubmissionGet(GetRequest<EmailSubmission<Set>>),
91 EmailSubmissionQuery(QueryRequest<EmailSubmission<Set>>),
92 EmailSubmissionQueryChanges(QueryChangesRequest<EmailSubmission<Set>>),
93 EmailSubmissionSet(SetRequest<EmailSubmission<Set>>),
94 VacationResponseGet(GetRequest<VacationResponse<Set>>),
95 VacationResponseSet(SetRequest<VacationResponse<Set>>),
96 SieveScriptGet(GetRequest<SieveScript<Set>>),
97 SieveScriptQuery(QueryRequest<SieveScript<Set>>),
98 SieveScriptValidate(SieveScriptValidateRequest),
99 SieveScriptSet(SetRequest<SieveScript<Set>>),
100 PrincipalGet(GetRequest<Principal<Set>>),
101 PrincipalQuery(QueryRequest<Principal<Set>>),
102 PrincipalQueryChanges(QueryChangesRequest<Principal<Set>>),
103 PrincipalSet(SetRequest<Principal<Set>>),
104}
105
106impl Arguments {
107 pub fn changes(params: RequestParams, since_state: String) -> Self {
108 Arguments::Changes(ChangesRequest::new(params, since_state))
109 }
110
111 pub fn push_get(params: RequestParams) -> Self {
112 Arguments::PushGet(GetRequest::new(params))
113 }
114
115 pub fn push_set(params: RequestParams) -> Self {
116 Arguments::PushSet(SetRequest::new(params))
117 }
118
119 pub fn blob_copy(params: RequestParams, from_account_id: String) -> Self {
120 Arguments::BlobCopy(CopyBlobRequest::new(params, from_account_id))
121 }
122
123 pub fn mailbox_get(params: RequestParams) -> Self {
124 Arguments::MailboxGet(GetRequest::new(params))
125 }
126
127 pub fn mailbox_query(params: RequestParams) -> Self {
128 Arguments::MailboxQuery(QueryRequest::new(params))
129 }
130
131 pub fn mailbox_query_changes(params: RequestParams, since_query_state: String) -> Self {
132 Arguments::MailboxQueryChanges(QueryChangesRequest::new(params, since_query_state))
133 }
134
135 pub fn mailbox_set(params: RequestParams) -> Self {
136 Arguments::MailboxSet(SetRequest::new(params))
137 }
138
139 pub fn thread_get(params: RequestParams) -> Self {
140 Arguments::ThreadGet(GetRequest::new(params))
141 }
142
143 pub fn email_get(params: RequestParams) -> Self {
144 Arguments::EmailGet(GetRequest::new(params))
145 }
146
147 pub fn email_query(params: RequestParams) -> Self {
148 Arguments::EmailQuery(QueryRequest::new(params))
149 }
150
151 pub fn email_query_changes(params: RequestParams, since_query_state: String) -> Self {
152 Arguments::EmailQueryChanges(QueryChangesRequest::new(params, since_query_state))
153 }
154
155 pub fn email_set(params: RequestParams) -> Self {
156 Arguments::EmailSet(SetRequest::new(params))
157 }
158
159 pub fn email_copy(params: RequestParams, from_account_id: String) -> Self {
160 Arguments::EmailCopy(CopyRequest::new(params, from_account_id))
161 }
162
163 pub fn email_import(params: RequestParams) -> Self {
164 Arguments::EmailImport(EmailImportRequest::new(params))
165 }
166
167 pub fn email_parse(params: RequestParams) -> Self {
168 Arguments::EmailParse(EmailParseRequest::new(params))
169 }
170
171 pub fn search_snippet_get(params: RequestParams) -> Self {
172 Arguments::SearchSnippetGet(SearchSnippetGetRequest::new(params))
173 }
174
175 pub fn identity_get(params: RequestParams) -> Self {
176 Arguments::IdentityGet(GetRequest::new(params))
177 }
178
179 pub fn identity_set(params: RequestParams) -> Self {
180 Arguments::IdentitySet(SetRequest::new(params))
181 }
182
183 pub fn email_submission_get(params: RequestParams) -> Self {
184 Arguments::EmailSubmissionGet(GetRequest::new(params))
185 }
186
187 pub fn email_submission_query(params: RequestParams) -> Self {
188 Arguments::EmailSubmissionQuery(QueryRequest::new(params))
189 }
190
191 pub fn email_submission_query_changes(
192 params: RequestParams,
193 since_query_state: String,
194 ) -> Self {
195 Arguments::EmailSubmissionQueryChanges(QueryChangesRequest::new(params, since_query_state))
196 }
197
198 pub fn email_submission_set(params: RequestParams) -> Self {
199 Arguments::EmailSubmissionSet(SetRequest::new(params))
200 }
201
202 pub fn vacation_response_get(params: RequestParams) -> Self {
203 Arguments::VacationResponseGet(GetRequest::new(params))
204 }
205
206 pub fn vacation_response_set(params: RequestParams) -> Self {
207 Arguments::VacationResponseSet(SetRequest::new(params))
208 }
209
210 pub fn sieve_script_get(params: RequestParams) -> Self {
211 Arguments::SieveScriptGet(GetRequest::new(params))
212 }
213
214 pub fn sieve_script_query(params: RequestParams) -> Self {
215 Arguments::SieveScriptQuery(QueryRequest::new(params))
216 }
217
218 pub fn sieve_script_validate(params: RequestParams, blob_id: impl Into<String>) -> Self {
219 Arguments::SieveScriptValidate(SieveScriptValidateRequest::new(params, blob_id))
220 }
221
222 pub fn sieve_script_set(params: RequestParams) -> Self {
223 Arguments::SieveScriptSet(SetRequest::new(params))
224 }
225
226 pub fn principal_get(params: RequestParams) -> Self {
227 Arguments::PrincipalGet(GetRequest::new(params))
228 }
229
230 pub fn principal_query(params: RequestParams) -> Self {
231 Arguments::PrincipalQuery(QueryRequest::new(params))
232 }
233
234 pub fn principal_query_changes(params: RequestParams, since_query_state: String) -> Self {
235 Arguments::PrincipalQueryChanges(QueryChangesRequest::new(params, since_query_state))
236 }
237
238 pub fn principal_set(params: RequestParams) -> Self {
239 Arguments::PrincipalSet(SetRequest::new(params))
240 }
241
242 pub fn changes_mut(&mut self) -> &mut ChangesRequest {
243 match self {
244 Arguments::Changes(ref mut r) => r,
245 _ => unreachable!(),
246 }
247 }
248
249 pub fn push_get_mut(&mut self) -> &mut GetRequest<PushSubscription<Set>> {
250 match self {
251 Arguments::PushGet(ref mut r) => r,
252 _ => unreachable!(),
253 }
254 }
255
256 pub fn push_set_mut(&mut self) -> &mut SetRequest<PushSubscription<Set>> {
257 match self {
258 Arguments::PushSet(ref mut r) => r,
259 _ => unreachable!(),
260 }
261 }
262
263 pub fn blob_copy_mut(&mut self) -> &mut CopyBlobRequest {
264 match self {
265 Arguments::BlobCopy(ref mut r) => r,
266 _ => unreachable!(),
267 }
268 }
269
270 pub fn mailbox_get_mut(&mut self) -> &mut GetRequest<Mailbox<Set>> {
271 match self {
272 Arguments::MailboxGet(ref mut r) => r,
273 _ => unreachable!(),
274 }
275 }
276
277 pub fn mailbox_query_mut(&mut self) -> &mut QueryRequest<Mailbox<Set>> {
278 match self {
279 Arguments::MailboxQuery(ref mut r) => r,
280 _ => unreachable!(),
281 }
282 }
283
284 pub fn mailbox_query_changes_mut(&mut self) -> &mut QueryChangesRequest<Mailbox<Set>> {
285 match self {
286 Arguments::MailboxQueryChanges(ref mut r) => r,
287 _ => unreachable!(),
288 }
289 }
290
291 pub fn mailbox_set_mut(&mut self) -> &mut SetRequest<Mailbox<Set>> {
292 match self {
293 Arguments::MailboxSet(ref mut r) => r,
294 _ => unreachable!(),
295 }
296 }
297
298 pub fn thread_get_mut(&mut self) -> &mut GetRequest<Thread> {
299 match self {
300 Arguments::ThreadGet(ref mut r) => r,
301 _ => unreachable!(),
302 }
303 }
304
305 pub fn email_get_mut(&mut self) -> &mut GetRequest<Email<Set>> {
306 match self {
307 Arguments::EmailGet(ref mut r) => r,
308 _ => unreachable!(),
309 }
310 }
311
312 pub fn email_query_mut(&mut self) -> &mut QueryRequest<Email<Set>> {
313 match self {
314 Arguments::EmailQuery(ref mut r) => r,
315 _ => unreachable!(),
316 }
317 }
318
319 pub fn email_query_changes_mut(&mut self) -> &mut QueryChangesRequest<Email<Set>> {
320 match self {
321 Arguments::EmailQueryChanges(ref mut r) => r,
322 _ => unreachable!(),
323 }
324 }
325
326 pub fn email_set_mut(&mut self) -> &mut SetRequest<Email<Set>> {
327 match self {
328 Arguments::EmailSet(ref mut r) => r,
329 _ => unreachable!(),
330 }
331 }
332
333 pub fn email_copy_mut(&mut self) -> &mut CopyRequest<Email<Set>> {
334 match self {
335 Arguments::EmailCopy(ref mut r) => r,
336 _ => unreachable!(),
337 }
338 }
339
340 pub fn email_import_mut(&mut self) -> &mut EmailImportRequest {
341 match self {
342 Arguments::EmailImport(ref mut r) => r,
343 _ => unreachable!(),
344 }
345 }
346
347 pub fn email_parse_mut(&mut self) -> &mut EmailParseRequest {
348 match self {
349 Arguments::EmailParse(ref mut r) => r,
350 _ => unreachable!(),
351 }
352 }
353
354 pub fn search_snippet_get_mut(&mut self) -> &mut SearchSnippetGetRequest {
355 match self {
356 Arguments::SearchSnippetGet(ref mut r) => r,
357 _ => unreachable!(),
358 }
359 }
360
361 pub fn identity_get_mut(&mut self) -> &mut GetRequest<Identity<Set>> {
362 match self {
363 Arguments::IdentityGet(ref mut r) => r,
364 _ => unreachable!(),
365 }
366 }
367
368 pub fn identity_set_mut(&mut self) -> &mut SetRequest<Identity<Set>> {
369 match self {
370 Arguments::IdentitySet(ref mut r) => r,
371 _ => unreachable!(),
372 }
373 }
374
375 pub fn email_submission_get_mut(&mut self) -> &mut GetRequest<EmailSubmission<Set>> {
376 match self {
377 Arguments::EmailSubmissionGet(ref mut r) => r,
378 _ => unreachable!(),
379 }
380 }
381
382 pub fn email_submission_query_mut(&mut self) -> &mut QueryRequest<EmailSubmission<Set>> {
383 match self {
384 Arguments::EmailSubmissionQuery(ref mut r) => r,
385 _ => unreachable!(),
386 }
387 }
388
389 pub fn email_submission_query_changes_mut(
390 &mut self,
391 ) -> &mut QueryChangesRequest<EmailSubmission<Set>> {
392 match self {
393 Arguments::EmailSubmissionQueryChanges(ref mut r) => r,
394 _ => unreachable!(),
395 }
396 }
397
398 pub fn email_submission_set_mut(&mut self) -> &mut SetRequest<EmailSubmission<Set>> {
399 match self {
400 Arguments::EmailSubmissionSet(ref mut r) => r,
401 _ => unreachable!(),
402 }
403 }
404
405 pub fn vacation_response_get_mut(&mut self) -> &mut GetRequest<VacationResponse<Set>> {
406 match self {
407 Arguments::VacationResponseGet(ref mut r) => r,
408 _ => unreachable!(),
409 }
410 }
411
412 pub fn vacation_response_set_mut(&mut self) -> &mut SetRequest<VacationResponse<Set>> {
413 match self {
414 Arguments::VacationResponseSet(ref mut r) => r,
415 _ => unreachable!(),
416 }
417 }
418
419 pub fn sieve_script_get_mut(&mut self) -> &mut GetRequest<SieveScript<Set>> {
420 match self {
421 Arguments::SieveScriptGet(ref mut r) => r,
422 _ => unreachable!(),
423 }
424 }
425
426 pub fn sieve_script_query_mut(&mut self) -> &mut QueryRequest<SieveScript<Set>> {
427 match self {
428 Arguments::SieveScriptQuery(ref mut r) => r,
429 _ => unreachable!(),
430 }
431 }
432
433 pub fn sieve_script_validate_mut(&mut self) -> &mut SieveScriptValidateRequest {
434 match self {
435 Arguments::SieveScriptValidate(ref mut r) => r,
436 _ => unreachable!(),
437 }
438 }
439
440 pub fn sieve_script_set_mut(&mut self) -> &mut SetRequest<SieveScript<Set>> {
441 match self {
442 Arguments::SieveScriptSet(ref mut r) => r,
443 _ => unreachable!(),
444 }
445 }
446
447 pub fn principal_get_mut(&mut self) -> &mut GetRequest<Principal<Set>> {
448 match self {
449 Arguments::PrincipalGet(ref mut r) => r,
450 _ => unreachable!(),
451 }
452 }
453
454 pub fn principal_query_mut(&mut self) -> &mut QueryRequest<Principal<Set>> {
455 match self {
456 Arguments::PrincipalQuery(ref mut r) => r,
457 _ => unreachable!(),
458 }
459 }
460
461 pub fn principal_query_changes_mut(&mut self) -> &mut QueryChangesRequest<Principal<Set>> {
462 match self {
463 Arguments::PrincipalQueryChanges(ref mut r) => r,
464 _ => unreachable!(),
465 }
466 }
467
468 pub fn principal_set_mut(&mut self) -> &mut SetRequest<Principal<Set>> {
469 match self {
470 Arguments::PrincipalSet(ref mut r) => r,
471 _ => unreachable!(),
472 }
473 }
474}
475
476impl<'x> Request<'x> {
477 pub fn new(client: &'x Client) -> Self {
478 Request {
479 using: vec![URI::Core, URI::Mail],
480 method_calls: vec![],
481 created_ids: None,
482 account_id: client.default_account_id().to_string(),
483 client,
484 }
485 }
486
487 pub fn account_id(mut self, account_id: impl Into<String>) -> Self {
488 self.account_id = account_id.into();
489 self
490 }
491
492 #[maybe_async::maybe_async]
493 pub async fn send(self) -> crate::Result<Response<TaggedMethodResponse>> {
494 self.client.send(&self).await
495 }
496
497 #[cfg(feature = "websockets")]
498 pub async fn send_ws(self) -> crate::Result<String> {
499 self.client.send_ws(self).await
500 }
501
502 #[maybe_async::maybe_async]
503 pub async fn send_single<T>(self) -> crate::Result<T>
504 where
505 T: DeserializeOwned,
506 {
507 let response: Response<SingleMethodResponse<T>> = self.client.send(&self).await?;
508 match response
509 .unwrap_method_responses()
510 .pop()
511 .ok_or_else(|| Error::Internal("Server returned no results".to_string()))?
512 {
513 SingleMethodResponse::Ok((_, response, _)) => Ok(response),
514 SingleMethodResponse::Error((_, err, _)) => Err(err.into()),
515 }
516 }
517
518 pub fn params(&self, method: Method) -> RequestParams {
519 RequestParams {
520 account_id: self.account_id.clone(),
521 method,
522 call_id: self.method_calls.len(),
523 }
524 }
525
526 pub fn add_method_call(&mut self, method: Method, arguments: Arguments) -> &mut Arguments {
527 let call_id = format!("s{}", self.method_calls.len());
528 self.method_calls.push((method, arguments, call_id));
529 &mut self.method_calls.last_mut().unwrap().1
530 }
531
532 pub fn add_capability(&mut self, uri: URI) {
533 if !self.using.contains(&uri) {
534 self.using.push(uri);
535 }
536 }
537
538 pub fn last_result_reference(&self, path: impl Into<String>) -> ResultReference {
539 let last_method = self.method_calls.last().unwrap();
540 ResultReference {
541 result_of: last_method.2.clone(),
542 name: last_method.0,
543 path: path.into(),
544 }
545 }
546}
547
548impl ResultReference {
549 pub fn new(method: Method, call_id: usize, path: impl Into<String>) -> Self {
550 ResultReference {
551 result_of: format!("s{}", call_id),
552 name: method,
553 path: path.into(),
554 }
555 }
556}