jmap_client/core/
copy.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 ahash::AHashMap;
13use serde::{Deserialize, Serialize};
14
15use crate::Error;
16
17use super::{
18    set::{SetError, SetObject},
19    RequestParams,
20};
21
22#[derive(Debug, Clone, Serialize)]
23pub struct CopyRequest<O: SetObject> {
24    #[serde(rename = "fromAccountId")]
25    from_account_id: String,
26
27    #[serde(rename = "ifFromInState")]
28    #[serde(skip_serializing_if = "Option::is_none")]
29    if_from_in_state: Option<String>,
30
31    #[serde(rename = "accountId")]
32    account_id: String,
33
34    #[serde(rename = "ifInState")]
35    #[serde(skip_serializing_if = "Option::is_none")]
36    if_in_state: Option<String>,
37
38    #[serde(rename = "create")]
39    create: AHashMap<String, O>,
40
41    #[serde(rename = "onSuccessDestroyOriginal")]
42    on_success_destroy_original: bool,
43
44    #[serde(rename = "destroyFromIfInState")]
45    #[serde(skip_serializing_if = "Option::is_none")]
46    destroy_from_if_in_state: Option<String>,
47}
48
49#[derive(Debug, Clone, Deserialize)]
50pub struct CopyResponse<O: SetObject> {
51    #[serde(rename = "fromAccountId")]
52    from_account_id: String,
53
54    #[serde(rename = "accountId")]
55    account_id: String,
56
57    #[serde(rename = "oldState")]
58    old_state: Option<String>,
59
60    #[serde(rename = "newState")]
61    new_state: String,
62
63    #[serde(rename = "created")]
64    created: Option<AHashMap<String, O>>,
65
66    #[serde(rename = "notCreated")]
67    not_created: Option<AHashMap<String, SetError<O::Property>>>,
68}
69
70impl<T: SetObject> CopyRequest<T> {
71    pub fn new(params: RequestParams, from_account_id: String) -> Self {
72        CopyRequest {
73            from_account_id,
74            if_from_in_state: None,
75            account_id: params.account_id,
76            if_in_state: None,
77            create: AHashMap::new(),
78            on_success_destroy_original: false,
79            destroy_from_if_in_state: None,
80        }
81    }
82
83    pub fn account_id(&mut self, account_id: impl Into<String>) -> &mut Self {
84        self.account_id = account_id.into();
85        self
86    }
87
88    pub fn if_from_in_state(&mut self, if_from_in_state: impl Into<String>) -> &mut Self {
89        self.if_from_in_state = Some(if_from_in_state.into());
90        self
91    }
92
93    pub fn if_in_state(&mut self, if_in_state: impl Into<String>) -> &mut Self {
94        self.if_in_state = Some(if_in_state.into());
95        self
96    }
97
98    pub fn create(&mut self, id: impl Into<String>) -> &mut T {
99        let id = id.into();
100        self.create.insert(id.clone(), T::new(None));
101        self.create.get_mut(&id).unwrap()
102    }
103
104    pub fn on_success_destroy_original(&mut self, on_success_destroy_original: bool) -> &mut Self {
105        self.on_success_destroy_original = on_success_destroy_original;
106        self
107    }
108
109    pub fn destroy_from_if_in_state(
110        &mut self,
111        destroy_from_if_in_state: impl Into<String>,
112    ) -> &mut Self {
113        self.destroy_from_if_in_state = Some(destroy_from_if_in_state.into());
114        self
115    }
116}
117
118impl<O: SetObject> CopyResponse<O> {
119    pub fn from_account_id(&self) -> &str {
120        &self.from_account_id
121    }
122
123    pub fn account_id(&self) -> &str {
124        &self.account_id
125    }
126
127    pub fn old_state(&self) -> Option<&str> {
128        self.old_state.as_deref()
129    }
130
131    pub fn new_state(&self) -> &str {
132        &self.new_state
133    }
134
135    pub fn created(&mut self, id: &str) -> crate::Result<O> {
136        if let Some(result) = self.created.as_mut().and_then(|r| r.remove(id)) {
137            Ok(result)
138        } else if let Some(error) = self.not_created.as_mut().and_then(|r| r.remove(id)) {
139            Err(error.to_string_error().into())
140        } else {
141            Err(Error::Internal(format!("Id {} not found.", id)))
142        }
143    }
144
145    pub fn take_created(&mut self) -> Option<Vec<O>> {
146        self.created
147            .take()
148            .map(|map| map.into_iter().map(|(_, v)| v).collect())
149    }
150
151    pub fn created_ids(&self) -> Option<impl Iterator<Item = &String>> {
152        self.created.as_ref().map(|map| map.keys())
153    }
154
155    pub fn not_created_ids(&self) -> Option<impl Iterator<Item = &String>> {
156        self.not_created.as_ref().map(|map| map.keys())
157    }
158}