1use 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 let mut object = T::new(None);
101 object.set_id(Some(id.clone()));
102 self.create.insert(id.clone(), object);
103 self.create.get_mut(&id).unwrap()
104 }
105
106 pub fn on_success_destroy_original(&mut self, on_success_destroy_original: bool) -> &mut Self {
107 self.on_success_destroy_original = on_success_destroy_original;
108 self
109 }
110
111 pub fn destroy_from_if_in_state(
112 &mut self,
113 destroy_from_if_in_state: impl Into<String>,
114 ) -> &mut Self {
115 self.destroy_from_if_in_state = Some(destroy_from_if_in_state.into());
116 self
117 }
118}
119
120impl<O: SetObject> CopyResponse<O> {
121 pub fn from_account_id(&self) -> &str {
122 &self.from_account_id
123 }
124
125 pub fn account_id(&self) -> &str {
126 &self.account_id
127 }
128
129 pub fn old_state(&self) -> Option<&str> {
130 self.old_state.as_deref()
131 }
132
133 pub fn new_state(&self) -> &str {
134 &self.new_state
135 }
136
137 pub fn created(&mut self, id: &str) -> crate::Result<O> {
138 if let Some(result) = self.created.as_mut().and_then(|r| r.remove(id)) {
139 Ok(result)
140 } else if let Some(error) = self.not_created.as_mut().and_then(|r| r.remove(id)) {
141 Err(error.to_string_error().into())
142 } else {
143 Err(Error::Internal(format!("Id {} not found.", id)))
144 }
145 }
146
147 pub fn take_created(&mut self) -> Option<Vec<O>> {
148 self.created
149 .take()
150 .map(|map| map.into_iter().map(|(_, v)| v).collect())
151 }
152
153 pub fn created_ids(&self) -> Option<impl Iterator<Item = &String>> {
154 self.created.as_ref().map(|map| map.keys())
155 }
156
157 pub fn not_created_ids(&self) -> Option<impl Iterator<Item = &String>> {
158 self.not_created.as_ref().map(|map| map.keys())
159 }
160}