jmap_client/core/
get.rs

1/*
2 * Copyright Stalwart Labs LLC See the COPYING
3 * file at the top-level directory of this distribution.
4 *
5 * Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 * https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 * <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
8 * option. This file may not be copied, modified, or distributed
9 * except according to those terms.
10 */
11
12use serde::{Deserialize, Serialize};
13
14use crate::Method;
15
16use super::{request::ResultReference, Object, RequestParams};
17
18pub trait GetObject: Object {
19    type GetArguments: Default;
20}
21
22#[derive(Debug, Clone, Serialize)]
23pub struct GetRequest<O: GetObject> {
24    #[serde(skip)]
25    method: (Method, usize),
26
27    #[serde(rename = "accountId")]
28    #[serde(skip_serializing_if = "Option::is_none")]
29    account_id: Option<String>,
30
31    #[serde(skip_serializing_if = "Option::is_none")]
32    ids: Option<Vec<String>>,
33
34    #[serde(rename = "#ids")]
35    #[serde(skip_deserializing)]
36    #[serde(skip_serializing_if = "Option::is_none")]
37    ids_ref: Option<ResultReference>,
38
39    #[serde(skip_serializing_if = "Option::is_none")]
40    properties: Option<Vec<O::Property>>,
41
42    #[serde(rename = "#properties")]
43    #[serde(skip_deserializing)]
44    #[serde(skip_serializing_if = "Option::is_none")]
45    properties_ref: Option<ResultReference>,
46
47    #[serde(flatten)]
48    arguments: O::GetArguments,
49}
50
51#[derive(Debug, Clone, Deserialize)]
52pub struct GetResponse<T> {
53    #[serde(rename = "accountId")]
54    account_id: Option<String>,
55
56    state: String,
57
58    list: Vec<T>,
59
60    #[serde(rename = "notFound")]
61    not_found: Vec<String>,
62}
63
64impl<O: GetObject> GetRequest<O> {
65    pub fn new(params: RequestParams) -> Self {
66        GetRequest {
67            account_id: if O::requires_account_id() {
68                params.account_id.into()
69            } else {
70                None
71            },
72            method: (params.method, params.call_id),
73            ids: None,
74            ids_ref: None,
75            properties: None,
76            properties_ref: None,
77            arguments: O::GetArguments::default(),
78        }
79    }
80
81    pub fn account_id(&mut self, account_id: impl Into<String>) -> &mut Self {
82        if O::requires_account_id() {
83            self.account_id = Some(account_id.into());
84        }
85        self
86    }
87
88    pub fn ids<U, V>(&mut self, ids: U) -> &mut Self
89    where
90        U: IntoIterator<Item = V>,
91        V: Into<String>,
92    {
93        self.ids = Some(ids.into_iter().map(|v| v.into()).collect());
94        self.ids_ref = None;
95        self
96    }
97
98    pub fn ids_ref(&mut self, reference: ResultReference) -> &mut Self {
99        self.ids_ref = reference.into();
100        self.ids = None;
101        self
102    }
103
104    pub fn properties(&mut self, properties: impl IntoIterator<Item = O::Property>) -> &mut Self {
105        self.properties = Some(properties.into_iter().collect());
106        self.properties_ref = None;
107        self
108    }
109
110    pub fn properties_ref(&mut self, reference: ResultReference) -> &mut Self {
111        self.properties_ref = Some(reference);
112        self.properties = None;
113        self
114    }
115
116    pub fn arguments(&mut self) -> &mut O::GetArguments {
117        &mut self.arguments
118    }
119
120    pub fn result_reference(&self, property: O::Property) -> ResultReference {
121        ResultReference::new(
122            self.method.0,
123            self.method.1,
124            format!("/list/*/{}", property),
125        )
126    }
127}
128
129impl<O> GetResponse<O> {
130    pub fn account_id(&self) -> Option<&str> {
131        self.account_id.as_deref()
132    }
133
134    pub fn state(&self) -> &str {
135        &self.state
136    }
137
138    pub fn take_state(&mut self) -> String {
139        std::mem::take(&mut self.state)
140    }
141
142    pub fn list(&self) -> &[O] {
143        &self.list
144    }
145
146    pub fn not_found(&self) -> &[String] {
147        &self.not_found
148    }
149
150    pub fn take_list(&mut self) -> Vec<O> {
151        std::mem::take(&mut self.list)
152    }
153    pub fn pop(&mut self) -> Option<O> {
154        self.list.pop()
155    }
156
157    pub fn take_not_found(&mut self) -> Vec<String> {
158        std::mem::take(&mut self.not_found)
159    }
160}