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 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}