platform_value/btreemap_extensions/
mod.rs

1#[cfg(feature = "json")]
2use serde_json::Value as JsonValue;
3use std::borrow::Borrow;
4use std::collections::BTreeMap;
5use std::convert::TryFrom;
6#[cfg(feature = "json")]
7use std::convert::TryInto;
8use std::iter::FromIterator;
9
10use crate::{BinaryData, Error, Identifier, Value, ValueMap};
11
12pub(crate) mod btreemap_field_replacement;
13mod btreemap_mut_value_extensions;
14mod btreemap_path_extensions;
15mod btreemap_path_insertion_extensions;
16mod btreemap_removal_extensions;
17mod btreemap_removal_inner_value_extensions;
18mod equal_underlying_data;
19
20pub use btreemap_field_replacement::BTreeValueMapReplacementPathHelper;
21pub use btreemap_mut_value_extensions::BTreeMutValueMapHelper;
22pub use btreemap_path_extensions::BTreeValueMapPathHelper;
23pub use btreemap_path_insertion_extensions::BTreeValueMapInsertionPathHelper;
24pub use btreemap_removal_extensions::BTreeValueRemoveFromMapHelper;
25pub use btreemap_removal_extensions::BTreeValueRemoveTupleFromMapHelper;
26pub use btreemap_removal_inner_value_extensions::BTreeValueRemoveInnerValueFromMapHelper;
27pub use equal_underlying_data::EqualUnderlyingData;
28
29pub trait BTreeValueMapHelper {
30    fn get_optional_identifier(&self, key: &str) -> Result<Option<Identifier>, Error>;
31    fn get_identifier(&self, key: &str) -> Result<Identifier, Error>;
32    fn get_optional_string(&self, key: &str) -> Result<Option<String>, Error>;
33    fn get_string(&self, key: &str) -> Result<String, Error>;
34    fn get_optional_str(&self, key: &str) -> Result<Option<&str>, Error>;
35    fn get_str(&self, key: &str) -> Result<&str, Error>;
36    fn get_optional_float(&self, key: &str) -> Result<Option<f64>, Error>;
37    fn get_float(&self, key: &str) -> Result<f64, Error>;
38    fn get_optional_integer<T>(&self, key: &str) -> Result<Option<T>, Error>
39    where
40        T: TryFrom<i128>
41            + TryFrom<u128>
42            + TryFrom<u64>
43            + TryFrom<i64>
44            + TryFrom<u32>
45            + TryFrom<i32>
46            + TryFrom<u16>
47            + TryFrom<i16>
48            + TryFrom<u8>
49            + TryFrom<i8>;
50    fn get_integer<T>(&self, key: &str) -> Result<T, Error>
51    where
52        T: TryFrom<i128>
53            + TryFrom<u128>
54            + TryFrom<u64>
55            + TryFrom<i64>
56            + TryFrom<u32>
57            + TryFrom<i32>
58            + TryFrom<u16>
59            + TryFrom<i16>
60            + TryFrom<u8>
61            + TryFrom<i8>;
62    fn get_optional_bool(&self, key: &str) -> Result<Option<bool>, Error>;
63    fn get_bool(&self, key: &str) -> Result<bool, Error>;
64    fn get_optional_inner_value_array<'a, I: FromIterator<&'a Value>>(
65        &'a self,
66        key: &str,
67    ) -> Result<Option<I>, Error>;
68    fn get_inner_value_array<'a, I: FromIterator<&'a Value>>(
69        &'a self,
70        key: &str,
71    ) -> Result<I, Error>;
72    fn get_optional_inner_map_in_array<
73        'a,
74        M: FromIterator<(String, &'a Value)>,
75        I: FromIterator<M>,
76    >(
77        &'a self,
78        key: &str,
79    ) -> Result<Option<I>, Error>;
80    fn get_inner_map_in_array<'a, M: FromIterator<(String, &'a Value)>, I: FromIterator<M>>(
81        &'a self,
82        key: &str,
83    ) -> Result<I, Error>;
84    fn get_optional_inner_string_array<I: FromIterator<String>>(
85        &self,
86        key: &str,
87    ) -> Result<Option<I>, Error>;
88    fn get_inner_string_array<I: FromIterator<String>>(&self, key: &str) -> Result<I, Error>;
89    fn get_optional_map(&self, key: &str) -> Result<Option<&Vec<(Value, Value)>>, Error>;
90    fn get_optional_str_value_map<'a, I: FromIterator<(String, &'a Value)>>(
91        &'a self,
92        key: &str,
93    ) -> Result<Option<I>, Error>;
94    fn get_inner_borrowed_str_value_map<'a, I: FromIterator<(String, &'a Value)>>(
95        &'a self,
96        key: &str,
97    ) -> Result<I, Error>;
98    #[cfg(feature = "json")]
99    fn get_optional_inner_str_json_value_map<I: FromIterator<(String, JsonValue)>>(
100        &self,
101        key: &str,
102    ) -> Result<Option<I>, Error>;
103    #[cfg(feature = "json")]
104    fn get_inner_str_json_value_map<I: FromIterator<(String, JsonValue)>>(
105        &self,
106        key: &str,
107    ) -> Result<I, Error>;
108    fn get_optional_hash256_bytes(&self, key: &str) -> Result<Option<[u8; 32]>, Error>;
109    fn get_hash256_bytes(&self, key: &str) -> Result<[u8; 32], Error>;
110    fn get_optional_identifier_bytes(&self, key: &str) -> Result<Option<Vec<u8>>, Error>;
111    fn get_identifier_bytes(&self, key: &str) -> Result<Vec<u8>, Error>;
112    fn get_optional_bytes(&self, key: &str) -> Result<Option<Vec<u8>>, Error>;
113    fn get_bytes(&self, key: &str) -> Result<Vec<u8>, Error>;
114    fn get_optional_binary_bytes(&self, key: &str) -> Result<Option<Vec<u8>>, Error>;
115    fn get_binary_bytes(&self, key: &str) -> Result<Vec<u8>, Error>;
116    fn get_optional_binary_data(&self, key: &str) -> Result<Option<BinaryData>, Error>;
117    fn get_binary_data(&self, key: &str) -> Result<BinaryData, Error>;
118    fn get_optional_u64(&self, key: &str) -> Result<Option<u64>, Error>;
119    fn get_u64(&self, key: &str) -> Result<u64, Error>;
120}
121
122impl<V> BTreeValueMapHelper for BTreeMap<String, V>
123where
124    V: Borrow<Value>,
125{
126    fn get_optional_identifier(&self, key: &str) -> Result<Option<Identifier>, Error> {
127        self.get(key)
128            .map(|v| v.borrow().to_identifier())
129            .transpose()
130    }
131
132    fn get_identifier(&self, key: &str) -> Result<Identifier, Error> {
133        self.get_optional_identifier(key)?.ok_or_else(|| {
134            Error::StructureError(format!("unable to get identifier property {key}"))
135        })
136    }
137
138    fn get_optional_string(&self, key: &str) -> Result<Option<String>, Error> {
139        self.get(key)
140            .map(|v| {
141                v.borrow()
142                    .as_text()
143                    .map(|str| str.to_string())
144                    .ok_or_else(|| Error::StructureError(format!("{key} must be a string")))
145            })
146            .transpose()
147    }
148
149    fn get_string(&self, key: &str) -> Result<String, Error> {
150        self.get_optional_string(key)?
151            .ok_or_else(|| Error::StructureError(format!("unable to get string property {key}")))
152    }
153
154    fn get_optional_str(&self, key: &str) -> Result<Option<&str>, Error> {
155        self.get(key)
156            .map(|v| {
157                v.borrow()
158                    .as_text()
159                    .ok_or_else(|| Error::StructureError(format!("{key} must be a string")))
160            })
161            .transpose()
162    }
163
164    fn get_str(&self, key: &str) -> Result<&str, Error> {
165        self.get_optional_str(key)?
166            .ok_or_else(|| Error::StructureError(format!("unable to get str property {key}")))
167    }
168
169    fn get_optional_integer<T>(&self, key: &str) -> Result<Option<T>, Error>
170    where
171        T: TryFrom<i128>
172            + TryFrom<u128>
173            + TryFrom<u64>
174            + TryFrom<i64>
175            + TryFrom<u32>
176            + TryFrom<i32>
177            + TryFrom<u16>
178            + TryFrom<i16>
179            + TryFrom<u8>
180            + TryFrom<i8>,
181    {
182        self.get(key)
183            .and_then(|v| {
184                let borrowed = v.borrow();
185                if borrowed.is_null() {
186                    None
187                } else {
188                    Some(v.borrow().to_integer())
189                }
190            })
191            .transpose()
192    }
193
194    fn get_integer<T>(&self, key: &str) -> Result<T, Error>
195    where
196        T: TryFrom<i128>
197            + TryFrom<u128>
198            + TryFrom<u64>
199            + TryFrom<i64>
200            + TryFrom<u32>
201            + TryFrom<i32>
202            + TryFrom<u16>
203            + TryFrom<i16>
204            + TryFrom<u8>
205            + TryFrom<i8>,
206    {
207        self.get_optional_integer(key)?
208            .ok_or_else(|| Error::StructureError(format!("unable to get integer property {key}")))
209    }
210
211    fn get_optional_bool(&self, key: &str) -> Result<Option<bool>, Error> {
212        self.get(key)
213            .and_then(|v| {
214                let borrowed = v.borrow();
215                if borrowed.is_null() {
216                    None
217                } else {
218                    Some(v.borrow().to_bool())
219                }
220            })
221            .transpose()
222    }
223
224    fn get_bool(&self, key: &str) -> Result<bool, Error> {
225        self.get_optional_bool(key)?
226            .ok_or_else(|| Error::StructureError(format!("unable to get bool property {key}")))
227    }
228
229    fn get_optional_inner_value_array<'a, I: FromIterator<&'a Value>>(
230        &'a self,
231        key: &str,
232    ) -> Result<Option<I>, Error> {
233        self.get(key)
234            .map(|v| {
235                v.borrow()
236                    .as_array()
237                    .map(|vec| vec.iter().collect())
238                    .ok_or_else(|| Error::StructureError(format!("{key} must be a bool")))
239            })
240            .transpose()
241    }
242
243    fn get_inner_value_array<'a, I: FromIterator<&'a Value>>(
244        &'a self,
245        key: &str,
246    ) -> Result<I, Error> {
247        self.get_optional_inner_value_array(key)?.ok_or_else(|| {
248            Error::StructureError(format!("unable to get inner value array property {key}"))
249        })
250    }
251
252    fn get_optional_inner_map_in_array<
253        'a,
254        M: FromIterator<(String, &'a Value)>,
255        I: FromIterator<M>,
256    >(
257        &'a self,
258        key: &str,
259    ) -> Result<Option<I>, Error> {
260        self.get(key)
261            .map(|v| {
262                v.borrow()
263                    .as_array()
264                    .map(|vec| {
265                        vec.iter()
266                            .map(|v| v.to_ref_string_map::<M>())
267                            .collect::<Result<I, Error>>()
268                    })
269                    .ok_or_else(|| Error::StructureError(format!("{key} must be a an array")))
270            })
271            .transpose()?
272            .transpose()
273    }
274
275    fn get_inner_map_in_array<'a, M: FromIterator<(String, &'a Value)>, I: FromIterator<M>>(
276        &'a self,
277        key: &str,
278    ) -> Result<I, Error> {
279        self.get_optional_inner_map_in_array(key)?.ok_or_else(|| {
280            Error::StructureError(format!("unable to get inner value array property {key}"))
281        })
282    }
283
284    fn get_optional_inner_string_array<I: FromIterator<String>>(
285        &self,
286        key: &str,
287    ) -> Result<Option<I>, Error> {
288        self.get(key)
289            .and_then(|v| {
290                let value = v.borrow();
291                if value.is_null() {
292                    None
293                } else {
294                    Some(value.to_array_ref().and_then(|inner| {
295                        inner
296                            .iter()
297                            .map(|v| {
298                                let Some(str) = v.as_text() else {
299                                    return Err(Error::StructureError(format!(
300                                        "{key} must be an string"
301                                    )));
302                                };
303                                Ok(str.to_string())
304                            })
305                            .collect::<Result<I, Error>>()
306                    }))
307                }
308            })
309            .transpose()
310    }
311
312    fn get_inner_string_array<I: FromIterator<String>>(&self, key: &str) -> Result<I, Error> {
313        self.get_optional_inner_string_array(key)?.ok_or_else(|| {
314            Error::StructureError(format!("unable to get inner string property {key}"))
315        })
316    }
317
318    fn get_optional_map(&self, key: &str) -> Result<Option<&ValueMap>, Error> {
319        self.get(key)
320            .and_then(|v| {
321                let value = v.borrow();
322                if value.is_null() {
323                    None
324                } else {
325                    Some(
326                        value
327                            .as_map()
328                            .ok_or_else(|| Error::StructureError(format!("{key} must be a map"))),
329                    )
330                }
331            })
332            .transpose()
333    }
334
335    fn get_optional_str_value_map<'a, I: FromIterator<(String, &'a Value)>>(
336        &'a self,
337        key: &str,
338    ) -> Result<Option<I>, Error> {
339        self.get(key)
340            .and_then(|v| {
341                let value = v.borrow();
342                if value.is_null() {
343                    None
344                } else {
345                    Some(value.to_map_ref().and_then(|inner| {
346                        inner
347                            .iter()
348                            .map(|(k, v)| Ok((k.to_text()?, v)))
349                            .collect::<Result<I, Error>>()
350                    }))
351                }
352            })
353            .transpose()
354    }
355
356    fn get_inner_borrowed_str_value_map<'a, I: FromIterator<(String, &'a Value)>>(
357        &'a self,
358        key: &str,
359    ) -> Result<I, Error> {
360        self.get_optional_str_value_map(key)?.ok_or_else(|| {
361            Error::StructureError(format!(
362                "unable to get borrowed str value map property {key}"
363            ))
364        })
365    }
366
367    #[cfg(feature = "json")]
368    fn get_optional_inner_str_json_value_map<I: FromIterator<(String, JsonValue)>>(
369        &self,
370        key: &str,
371    ) -> Result<Option<I>, Error> {
372        self.get(key)
373            .and_then(|v| {
374                let value = v.borrow();
375                if value.is_null() {
376                    None
377                } else {
378                    Some(value.to_map_ref().and_then(|inner| {
379                        inner
380                            .iter()
381                            .map(|(k, v)| Ok((k.to_text()?, v.clone().try_into()?)))
382                            .collect::<Result<I, Error>>()
383                    }))
384                }
385            })
386            .transpose()
387    }
388
389    #[cfg(feature = "json")]
390    fn get_inner_str_json_value_map<I: FromIterator<(String, JsonValue)>>(
391        &self,
392        key: &str,
393    ) -> Result<I, Error> {
394        self.get_optional_inner_str_json_value_map(key)?
395            .ok_or_else(|| {
396                Error::StructureError(format!(
397                    "unable to get borrowed str json value map property {key}"
398                ))
399            })
400    }
401
402    fn get_optional_hash256_bytes(&self, key: &str) -> Result<Option<[u8; 32]>, Error> {
403        self.get(key).map(|v| v.borrow().to_hash256()).transpose()
404    }
405
406    fn get_hash256_bytes(&self, key: &str) -> Result<[u8; 32], Error> {
407        self.get_optional_hash256_bytes(key)?
408            .ok_or_else(|| Error::StructureError(format!("unable to get hash256 property {key}")))
409    }
410
411    fn get_optional_bytes(&self, key: &str) -> Result<Option<Vec<u8>>, Error> {
412        self.get(key).map(|v| v.borrow().to_bytes()).transpose()
413    }
414
415    fn get_bytes(&self, key: &str) -> Result<Vec<u8>, Error> {
416        self.get_optional_bytes(key)?
417            .ok_or_else(|| Error::StructureError(format!("unable to get bytes property {key}")))
418    }
419
420    fn get_optional_identifier_bytes(&self, key: &str) -> Result<Option<Vec<u8>>, Error> {
421        self.get(key)
422            .map(|v| v.borrow().to_identifier_bytes())
423            .transpose()
424    }
425
426    fn get_identifier_bytes(&self, key: &str) -> Result<Vec<u8>, Error> {
427        self.get_optional_identifier_bytes(key)?
428            .ok_or_else(|| Error::StructureError(format!("unable to get bytes property {key}")))
429    }
430
431    fn get_optional_binary_bytes(&self, key: &str) -> Result<Option<Vec<u8>>, Error> {
432        self.get(key)
433            .map(|v| v.borrow().to_binary_bytes())
434            .transpose()
435    }
436
437    fn get_binary_bytes(&self, key: &str) -> Result<Vec<u8>, Error> {
438        self.get_optional_binary_bytes(key)?
439            .ok_or_else(|| Error::StructureError(format!("unable to get bytes property {key}")))
440    }
441
442    fn get_optional_binary_data(&self, key: &str) -> Result<Option<BinaryData>, Error> {
443        self.get(key)
444            .map(|v| v.borrow().to_binary_data())
445            .transpose()
446    }
447
448    fn get_binary_data(&self, key: &str) -> Result<BinaryData, Error> {
449        self.get_optional_binary_data(key)?.ok_or_else(|| {
450            Error::StructureError(format!("unable to get binary data property {key}"))
451        })
452    }
453
454    fn get_optional_float(&self, key: &str) -> Result<Option<f64>, Error> {
455        self.get(key)
456            .and_then(|v| {
457                let borrowed = v.borrow();
458                if borrowed.is_null() {
459                    None
460                } else {
461                    Some(v.borrow().to_float())
462                }
463            })
464            .transpose()
465    }
466
467    fn get_float(&self, key: &str) -> Result<f64, Error> {
468        self.get_optional_float(key)?
469            .ok_or_else(|| Error::StructureError(format!("unable to get float property {key}")))
470    }
471
472    fn get_optional_u64(&self, key: &str) -> Result<Option<u64>, Error> {
473        Ok(self.get(key).and_then(|v| {
474            let borrowed = v.borrow();
475            if borrowed.is_null() {
476                None
477            } else {
478                v.borrow().as_integer::<u64>()
479            }
480        }))
481    }
482
483    fn get_u64(&self, key: &str) -> Result<u64, Error> {
484        self.get_optional_u64(key)?
485            .ok_or_else(|| Error::StructureError(format!("unable to get u64 property {key}")))
486    }
487}