1use crate::models::FlagCollection;
4use alloc::format;
5use alloc::vec::Vec;
6use core::hash::BuildHasherDefault;
7use core::{convert::TryFrom, fmt::Debug};
8use fnv::FnvHasher;
9use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer};
10use serde_json::Value;
11use strum::IntoEnumIterator;
12
13pub type HashMap<K, V> = hashbrown::HashMap<K, V, BuildHasherDefault<FnvHasher>>;
14
15fn serialize_flag<F, S>(flags: &FlagCollection<F>, s: S) -> Result<S::Ok, S::Error>
16where
17 F: Serialize + IntoEnumIterator,
18 S: Serializer,
19{
20 let flags_value_result: Result<Value, serde_json::Error> = serde_json::to_value(flags);
21 match flags_value_result {
22 Ok(flags_as_value) => {
23 let flag_vec_result: Result<Vec<u32>, serde_json::Error> =
24 serde_json::from_value(flags_as_value);
25 match flag_vec_result {
26 Ok(flags_vec) => s.serialize_u32(flags_vec.iter().sum()),
27 Err(_) => {
28 Err(ser::Error::custom("SerdeIntermediateStepError: Failed to turn flags into `Vec<u32>` during serialization"))
30 }
31 }
32 }
33 Err(_) => Err(ser::Error::custom(
34 "SerdeIntermediateStepError: Failed to turn flags into `Value` during serialization",
35 )),
36 }
37}
38
39fn deserialize_flags<'de, D, F>(d: D) -> Result<FlagCollection<F>, D::Error>
40where
41 F: Serialize + IntoEnumIterator + Debug,
42 D: Deserializer<'de>,
43{
44 let flags_u32 = u32::deserialize(d)?;
45 FlagCollection::<F>::try_from(flags_u32).map_err(|_e| {
46 de::Error::custom(format!(
47 "SerdeIntermediateStepError: Failed to turn `u32` into `FlagCollection<{}>` during deserialization",
48 core::any::type_name::<F>()
49 ))
50 })
51}
52
53pub(crate) mod txn_flags {
56 use core::fmt::Debug;
57
58 use crate::_serde::{deserialize_flags, serialize_flag};
59
60 use serde::{Deserializer, Serialize, Serializer};
61
62 use crate::models::FlagCollection;
63 use strum::IntoEnumIterator;
64
65 pub fn serialize<F, S>(flags: &FlagCollection<F>, s: S) -> Result<S::Ok, S::Error>
66 where
67 F: Serialize + IntoEnumIterator + Debug,
68 S: Serializer,
69 {
70 if flags.0.is_empty() {
71 s.serialize_u32(0)
72 } else {
73 serialize_flag(flags, s)
74 }
75 }
76
77 pub fn deserialize<'de, F, D>(d: D) -> Result<FlagCollection<F>, D::Error>
78 where
79 F: Serialize + IntoEnumIterator + Debug,
80 D: Deserializer<'de>,
81 {
82 let flags_vec_result: Result<FlagCollection<F>, D::Error> = deserialize_flags(d);
83 match flags_vec_result {
84 Ok(flags_vec) => {
85 if flags_vec.0.is_empty() {
86 Ok(FlagCollection::<F>::default())
87 } else {
88 Ok(flags_vec)
89 }
90 }
91 Err(error) => Err(error),
92 }
93 }
94}
95
96pub(crate) mod lgr_obj_flags {
97 use core::fmt::Debug;
98
99 use crate::_serde::{deserialize_flags, serialize_flag};
100 use crate::models::FlagCollection;
101 use serde::{Deserializer, Serialize, Serializer};
102 use strum::IntoEnumIterator;
103
104 pub fn serialize<F, S>(flags: &FlagCollection<F>, s: S) -> Result<S::Ok, S::Error>
105 where
106 F: Serialize + IntoEnumIterator,
107 S: Serializer,
108 {
109 if !flags.0.is_empty() {
110 serialize_flag(flags, s)
111 } else {
112 s.serialize_u32(0)
113 }
114 }
115
116 pub fn deserialize<'de, F, D>(d: D) -> Result<FlagCollection<F>, D::Error>
117 where
118 F: Serialize + IntoEnumIterator + Debug,
119 D: Deserializer<'de>,
120 {
121 deserialize_flags(d)
122 }
123}
124
125#[macro_export]
135macro_rules! serde_with_tag {
136 (
137 $(#[$attr:meta])*
138 pub struct $name:ident<$lt:lifetime> {
139 $(
140 $(#[$doc:meta])*
141 pub $field:ident: $ty:ty,
142 )*
143 }
144 ) => {
145 $(#[$attr])*
146 pub struct $name<$lt> {
147 $(
148 $(#[$doc])*
149 pub $field: $ty,
150 )*
151 }
152
153 impl<$lt> ::serde::Serialize for $name<$lt> {
154 fn serialize<S>(&self, serializer: S) -> ::core::result::Result<S::Ok, S::Error>
155 where
156 S: ::serde::Serializer
157 {
158 #[derive(::serde::Serialize)]
159 #[serde(rename_all = "PascalCase")]
160 #[::serde_with::skip_serializing_none]
161 struct Helper<$lt> {
162 $(
163 $field: $ty,
164 )*
165 }
166
167 let helper = Helper {
168 $(
169 $field: self.$field.clone(),
170 )*
171 };
172
173 let mut state = serializer.serialize_map(Some(1))?;
174 state.serialize_key(stringify!($name))?;
175 state.serialize_value(&helper)?;
176 state.end()
177 }
178 }
179
180 impl<'de: $lt, $lt> ::serde::Deserialize<'de> for $name<$lt> {
181 #[allow(non_snake_case)]
182 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
183 where
184 D: serde::Deserializer<'de>,
185 {
186 #[derive(::serde::Deserialize)]
187 #[serde(rename_all = "PascalCase")]
188 #[::serde_with::skip_serializing_none]
189 struct Helper<$lt> {
190 $(
191 $field: $ty,
192 )*
193 }
194
195 let hash_map: $crate::_serde::HashMap<&$lt str, Helper<$lt>> = $crate::_serde::HashMap::deserialize(deserializer)?;
196 let helper_result = hash_map.get(stringify!($name));
197
198 match helper_result {
199 Some(helper) => {
200 Ok(Self {
201 $(
202 $field: helper.$field.clone().into(),
203 )*
204 })
205 }
206 None => {
207 Err(::serde::de::Error::custom("SerdeIntermediateStepError: Unable to find model name as json key."))
208 }
209 }
210 }
211 }
212 };
213 (
214 $(#[$attr:meta])*
215 pub struct $name:ident {
216 $(
217 $(#[$doc:meta])*
218 pub $field:ident: $ty:ty,
219 )*
220 }
221 ) => {
222 $(#[$attr])*
223 pub struct $name {
224 $(
225 $(#[$doc])*
226 pub $field: $ty,
227 )*
228 }
229
230 impl ::serde::Serialize for $name {
231 fn serialize<S>(&self, serializer: S) -> ::core::result::Result<S::Ok, S::Error>
232 where
233 S: ::serde::Serializer
234 {
235 #[derive(::serde::Serialize)]
236 #[serde(rename_all = "PascalCase")]
237 #[::serde_with::skip_serializing_none]
238 struct Helper {
239 $(
240 $field: $ty,
241 )*
242 }
243
244 let helper = Helper {
245 $(
246 $field: self.$field.clone(),
247 )*
248 };
249
250 let mut state = serializer.serialize_map(Some(1))?;
251 state.serialize_key(stringify!($name))?;
252 state.serialize_value(&helper)?;
253 state.end()
254 }
255 }
256
257 impl<'de> ::serde::Deserialize<'de> for $name {
258 #[allow(non_snake_case)]
259 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
260 where
261 D: serde::Deserializer<'de>,
262 {
263 #[derive(::serde::Deserialize)]
264 #[serde(rename_all = "PascalCase")]
265 #[::serde_with::skip_serializing_none]
266 struct Helper {
267 $(
268 $field: $ty,
269 )*
270 }
271
272 let hash_map: $crate::_serde::HashMap<&'de str, Helper> = $crate::_serde::HashMap::deserialize(deserializer)?;
273 let helper_result = hash_map.get(stringify!($name));
274
275 match helper_result {
276 Some(helper) => {
277 Ok(Self {
278 $(
279 $field: helper.$field.clone().into(),
280 )*
281 })
282 }
283 None => {
284 Err(::serde::de::Error::custom("SerdeIntermediateStepError: Unable to find model name as json key."))
285 }
286 }
287 }
288 }
289 };
290}