Skip to main content

platform_value/
value_map.rs

1use crate::{Error, Value};
2use indexmap::IndexMap;
3use std::cmp::Ordering;
4use std::collections::BTreeMap;
5
6pub type ValueMap = Vec<(Value, Value)>;
7
8pub trait ValueMapHelper {
9    fn sort_by_keys(&mut self);
10    fn sort_by_keys_and_inner_maps(&mut self);
11    fn sort_by_lexicographical_byte_ordering_keys(&mut self);
12    fn sort_by_lexicographical_byte_ordering_keys_and_inner_maps(&mut self);
13    fn get_key(&self, search_key: &str) -> Result<&Value, Error>;
14    fn get_optional_key(&self, key: &str) -> Option<&Value>;
15    fn get_key_mut(&mut self, search_key: &str) -> Result<&mut Value, Error>;
16    fn get_optional_key_mut(&mut self, key: &str) -> Option<&mut Value>;
17    fn get_key_mut_or_insert(&mut self, key: &str, value: Value) -> &mut Value;
18    fn get_key_by_value_mut_or_insert(&mut self, search_key: &Value, value: Value) -> &mut Value;
19    fn insert_string_key_value(&mut self, key: String, value: Value);
20    fn remove_key(&mut self, search_key: &str) -> Result<Value, Error>;
21    fn remove_optional_key(&mut self, key: &str) -> Option<Value>;
22    fn remove_optional_key_if_null(&mut self, search_key: &str);
23    fn remove_optional_key_if_empty_array(&mut self, search_key: &str);
24    fn remove_optional_key_value(&mut self, search_key_value: &Value) -> Option<Value>;
25    fn from_btree_map<K: Into<Value> + Ord, V: Into<Value>>(btree_map: BTreeMap<K, V>) -> Self;
26}
27
28impl ValueMapHelper for ValueMap {
29    fn sort_by_keys(&mut self) {
30        self.sort_by(|(key1, _), (key2, _)| key1.partial_cmp(key2).unwrap_or(Ordering::Less));
31    }
32
33    fn sort_by_keys_and_inner_maps(&mut self) {
34        self.sort_by_keys();
35        self.iter_mut().for_each(|(_, v)| {
36            if let Value::Map(m) = v {
37                m.sort_by_keys_and_inner_maps()
38            }
39        });
40    }
41
42    fn sort_by_lexicographical_byte_ordering_keys(&mut self) {
43        self.sort_by(|(key1, _), (key2, _)| {
44            if key1.is_text() && key2.is_text() {
45                let key1 = key1.to_text().unwrap();
46                let key2 = key2.to_text().unwrap();
47                match key1.len().cmp(&key2.len()) {
48                    Ordering::Less => Ordering::Less,
49                    Ordering::Equal => key1.cmp(&key2),
50                    Ordering::Greater => Ordering::Greater,
51                }
52            } else {
53                key1.partial_cmp(key2).unwrap_or(Ordering::Less)
54            }
55        })
56    }
57
58    fn sort_by_lexicographical_byte_ordering_keys_and_inner_maps(&mut self) {
59        self.sort_by_lexicographical_byte_ordering_keys();
60        self.iter_mut().for_each(|(_, v)| {
61            if let Value::Map(m) = v {
62                m.sort_by_lexicographical_byte_ordering_keys_and_inner_maps()
63            }
64        });
65    }
66
67    fn get_key(&self, search_key: &str) -> Result<&Value, Error> {
68        self.get_optional_key(search_key)
69            .ok_or(Error::StructureError(format!(
70                "required property not found {search_key}"
71            )))
72    }
73
74    fn get_optional_key(&self, search_key: &str) -> Option<&Value> {
75        self.iter().find_map(|(key, value)| {
76            if let Value::Text(text) = key {
77                if text == search_key {
78                    Some(value)
79                } else {
80                    None
81                }
82            } else {
83                None
84            }
85        })
86    }
87
88    fn get_key_mut(&mut self, search_key: &str) -> Result<&mut Value, Error> {
89        self.get_optional_key_mut(search_key)
90            .ok_or(Error::StructureError(format!(
91                "{search_key} not found, but was required"
92            )))
93    }
94
95    fn get_optional_key_mut(&mut self, search_key: &str) -> Option<&mut Value> {
96        self.iter_mut().find_map(|(key, value)| {
97            if let Value::Text(text) = key {
98                if text == search_key {
99                    Some(value)
100                } else {
101                    None
102                }
103            } else {
104                None
105            }
106        })
107    }
108
109    fn get_key_mut_or_insert(&mut self, search_key: &str, value: Value) -> &mut Value {
110        let found = self.iter().position(|(key, _)| {
111            if let Value::Text(text) = key {
112                text == search_key
113            } else {
114                false
115            }
116        });
117        match found {
118            None => {
119                self.push((Value::Text(search_key.to_string()), value));
120                let (_, value) = self.last_mut().unwrap();
121                value
122            }
123            Some(pos) => {
124                let (_, value) = self.get_mut(pos).unwrap();
125                value
126            }
127        }
128    }
129
130    fn get_key_by_value_mut_or_insert(&mut self, search_key: &Value, value: Value) -> &mut Value {
131        let found = self.iter().position(|(key, _)| search_key == key);
132        match found {
133            None => {
134                self.push((search_key.clone(), value));
135                let (_, value) = self.last_mut().unwrap();
136                value
137            }
138            Some(pos) => {
139                let (_, value) = self.get_mut(pos).unwrap();
140                value
141            }
142        }
143    }
144
145    fn insert_string_key_value(&mut self, key: String, value: Value) {
146        self.push((key.into(), value))
147    }
148
149    fn remove_key(&mut self, search_key: &str) -> Result<Value, Error> {
150        self.iter()
151            .position(|(key, _)| {
152                if let Value::Text(text) = key {
153                    text == search_key
154                } else {
155                    false
156                }
157            })
158            .map(|pos| self.remove(pos).1)
159            .ok_or(Error::StructureError(format!(
160                "trying to remove a key {} from a ValueMap that was not found",
161                search_key
162            )))
163    }
164
165    fn remove_optional_key(&mut self, search_key: &str) -> Option<Value> {
166        self.iter()
167            .position(|(key, _)| {
168                if let Value::Text(text) = key {
169                    text == search_key
170                } else {
171                    false
172                }
173            })
174            .map(|pos| self.remove(pos).1)
175    }
176
177    fn remove_optional_key_if_null(&mut self, search_key: &str) {
178        self.iter()
179            .position(|(key, value)| {
180                if let Value::Text(text) = key {
181                    if text == search_key {
182                        value.is_null()
183                    } else {
184                        false
185                    }
186                } else {
187                    false
188                }
189            })
190            .map(|pos| self.remove(pos).1);
191    }
192
193    fn remove_optional_key_if_empty_array(&mut self, search_key: &str) {
194        self.iter()
195            .position(|(key, value)| {
196                if let Value::Text(text) = key {
197                    if text == search_key {
198                        if let Some(v) = value.as_array() {
199                            v.is_empty()
200                        } else {
201                            false
202                        }
203                    } else {
204                        false
205                    }
206                } else {
207                    false
208                }
209            })
210            .map(|pos| self.remove(pos).1);
211    }
212
213    fn remove_optional_key_value(&mut self, search_key_value: &Value) -> Option<Value> {
214        self.iter()
215            .position(|(key, _)| search_key_value == key)
216            .map(|pos| self.remove(pos).1)
217    }
218    fn from_btree_map<K: Into<Value> + Ord, V: Into<Value>>(btree_map: BTreeMap<K, V>) -> Self {
219        btree_map
220            .into_iter()
221            .map(|(k, v)| (k.into(), v.into()))
222            .collect()
223    }
224}
225
226#[cfg(test)]
227#[allow(clippy::items_after_test_module)]
228mod tests {
229    use super::*;
230
231    fn text(s: &str) -> Value {
232        Value::Text(s.to_string())
233    }
234
235    fn make_map(pairs: &[(&str, Value)]) -> ValueMap {
236        pairs.iter().map(|(k, v)| (text(k), v.clone())).collect()
237    }
238
239    // ---------------------------------------------------------------
240    // sort_by_keys
241    // ---------------------------------------------------------------
242
243    #[test]
244    fn sort_by_keys_mixed_text_keys() {
245        let mut map = make_map(&[
246            ("c", Value::U32(3)),
247            ("a", Value::U32(1)),
248            ("b", Value::U32(2)),
249        ]);
250        map.sort_by_keys();
251        let keys: Vec<_> = map.iter().map(|(k, _)| k.clone()).collect();
252        assert_eq!(keys, vec![text("a"), text("b"), text("c")]);
253    }
254
255    #[test]
256    fn sort_by_keys_mixed_types() {
257        // Integer keys should sort before text keys via PartialOrd on Value
258        let mut map: ValueMap = vec![
259            (text("z"), Value::U32(1)),
260            (Value::U32(5), Value::U32(2)),
261            (text("a"), Value::U32(3)),
262        ];
263        map.sort_by_keys();
264        // U32(5) < Text("a") < Text("z") by Value's PartialOrd (enum variant order)
265        assert_eq!(map[0].0, Value::U32(5));
266        assert_eq!(map[1].0, text("a"));
267        assert_eq!(map[2].0, text("z"));
268    }
269
270    // ---------------------------------------------------------------
271    // sort_by_lexicographical_byte_ordering_keys
272    // ---------------------------------------------------------------
273
274    #[test]
275    fn sort_by_lexicographical_byte_ordering_shorter_first() {
276        // "ab" (len 2) should come before "abc" (len 3)
277        let mut map = make_map(&[
278            ("abc", Value::U32(1)),
279            ("ab", Value::U32(2)),
280            ("a", Value::U32(3)),
281        ]);
282        map.sort_by_lexicographical_byte_ordering_keys();
283        let keys: Vec<_> = map.iter().map(|(k, _)| k.to_text().unwrap()).collect();
284        assert_eq!(keys, vec!["a", "ab", "abc"]);
285    }
286
287    #[test]
288    fn sort_by_lexicographical_byte_ordering_same_length_alphabetical() {
289        let mut map = make_map(&[
290            ("cb", Value::U32(1)),
291            ("ab", Value::U32(2)),
292            ("bb", Value::U32(3)),
293        ]);
294        map.sort_by_lexicographical_byte_ordering_keys();
295        let keys: Vec<_> = map.iter().map(|(k, _)| k.to_text().unwrap()).collect();
296        assert_eq!(keys, vec!["ab", "bb", "cb"]);
297    }
298
299    #[test]
300    fn sort_by_lexicographical_byte_ordering_non_text_keys_uses_partial_cmp() {
301        let mut map: ValueMap = vec![(Value::U32(10), Value::Null), (Value::U32(2), Value::Null)];
302        map.sort_by_lexicographical_byte_ordering_keys();
303        assert_eq!(map[0].0, Value::U32(2));
304        assert_eq!(map[1].0, Value::U32(10));
305    }
306
307    // ---------------------------------------------------------------
308    // get_key_mut_or_insert
309    // ---------------------------------------------------------------
310
311    #[test]
312    fn get_key_mut_or_insert_inserts_new() {
313        let mut map = make_map(&[("a", Value::U32(1))]);
314        let val = map.get_key_mut_or_insert("b", Value::U32(99));
315        assert_eq!(*val, Value::U32(99));
316        // Mutate the returned reference
317        *val = Value::U32(100);
318        assert_eq!(map.get_optional_key("b"), Some(&Value::U32(100)));
319    }
320
321    #[test]
322    fn get_key_mut_or_insert_returns_existing() {
323        let mut map = make_map(&[("a", Value::U32(1))]);
324        let val = map.get_key_mut_or_insert("a", Value::U32(99));
325        // Should return existing value, not the default
326        assert_eq!(*val, Value::U32(1));
327    }
328
329    #[test]
330    fn get_key_mut_or_insert_existing_is_mutable() {
331        let mut map = make_map(&[("a", Value::U32(1))]);
332        let val = map.get_key_mut_or_insert("a", Value::U32(99));
333        *val = Value::U32(42);
334        assert_eq!(map.get_optional_key("a"), Some(&Value::U32(42)));
335    }
336
337    // ---------------------------------------------------------------
338    // remove_optional_key_if_null
339    // ---------------------------------------------------------------
340
341    #[test]
342    fn remove_optional_key_if_null_removes_null() {
343        let mut map = make_map(&[("a", Value::Null), ("b", Value::U32(2))]);
344        map.remove_optional_key_if_null("a");
345        assert_eq!(map.get_optional_key("a"), None);
346        assert_eq!(map.get_optional_key("b"), Some(&Value::U32(2)));
347    }
348
349    #[test]
350    fn remove_optional_key_if_null_keeps_non_null() {
351        let mut map = make_map(&[("a", Value::U32(1))]);
352        map.remove_optional_key_if_null("a");
353        assert_eq!(map.get_optional_key("a"), Some(&Value::U32(1)));
354    }
355
356    #[test]
357    fn remove_optional_key_if_null_missing_key_is_noop() {
358        let mut map = make_map(&[("a", Value::U32(1))]);
359        map.remove_optional_key_if_null("missing");
360        assert_eq!(map.len(), 1);
361    }
362
363    // ---------------------------------------------------------------
364    // remove_optional_key_if_empty_array
365    // ---------------------------------------------------------------
366
367    #[test]
368    fn remove_optional_key_if_empty_array_removes_empty() {
369        let mut map = make_map(&[("a", Value::Array(vec![])), ("b", Value::U32(1))]);
370        map.remove_optional_key_if_empty_array("a");
371        assert_eq!(map.get_optional_key("a"), None);
372        assert_eq!(map.get_optional_key("b"), Some(&Value::U32(1)));
373    }
374
375    #[test]
376    fn remove_optional_key_if_empty_array_keeps_non_empty() {
377        let mut map = make_map(&[("a", Value::Array(vec![Value::U32(1)]))]);
378        map.remove_optional_key_if_empty_array("a");
379        assert!(map.get_optional_key("a").is_some());
380    }
381
382    #[test]
383    fn remove_optional_key_if_empty_array_keeps_non_array() {
384        let mut map = make_map(&[("a", Value::U32(42))]);
385        map.remove_optional_key_if_empty_array("a");
386        assert_eq!(map.get_optional_key("a"), Some(&Value::U32(42)));
387    }
388
389    #[test]
390    fn remove_optional_key_if_empty_array_missing_key_is_noop() {
391        let mut map = make_map(&[("a", Value::U32(1))]);
392        map.remove_optional_key_if_empty_array("missing");
393        assert_eq!(map.len(), 1);
394    }
395
396    // ---------------------------------------------------------------
397    // into_btree_string_map
398    // ---------------------------------------------------------------
399
400    #[test]
401    fn into_btree_string_map_valid_conversion() {
402        let val = Value::Map(make_map(&[("b", Value::U32(2)), ("a", Value::U32(1))]));
403        let btree = val.into_btree_string_map().unwrap();
404        assert_eq!(btree.get("a"), Some(&Value::U32(1)));
405        assert_eq!(btree.get("b"), Some(&Value::U32(2)));
406        // BTreeMap should be sorted by key
407        let keys: Vec<_> = btree.keys().collect();
408        assert_eq!(keys, vec!["a", "b"]);
409    }
410
411    #[test]
412    fn into_btree_string_map_error_on_non_string_keys() {
413        let val = Value::Map(vec![(Value::U32(1), Value::U32(2))]);
414        let result = val.into_btree_string_map();
415        assert!(result.is_err());
416    }
417
418    #[test]
419    fn into_btree_string_map_error_on_non_map() {
420        let val = Value::Bool(true);
421        let result = val.into_btree_string_map();
422        assert!(result.is_err());
423    }
424
425    // ---------------------------------------------------------------
426    // map_ref_into_indexed_string_map
427    // ---------------------------------------------------------------
428
429    #[test]
430    fn map_ref_into_indexed_string_map_sorts_by_integer_key() {
431        let map: ValueMap = vec![
432            (
433                text("second"),
434                Value::Map(make_map(&[("pos", Value::U32(2))])),
435            ),
436            (
437                text("first"),
438                Value::Map(make_map(&[("pos", Value::U32(1))])),
439            ),
440            (
441                text("third"),
442                Value::Map(make_map(&[("pos", Value::U32(3))])),
443            ),
444        ];
445        let indexed = Value::map_ref_into_indexed_string_map::<u32>(&map, "pos").unwrap();
446        let keys: Vec<_> = indexed.keys().collect();
447        assert_eq!(keys, vec!["first", "second", "third"]);
448    }
449
450    #[test]
451    fn map_ref_into_indexed_string_map_error_missing_sort_key() {
452        let map: ValueMap = vec![(
453            text("item"),
454            Value::Map(make_map(&[("other", Value::U32(1))])),
455        )];
456        let result = Value::map_ref_into_indexed_string_map::<u32>(&map, "pos");
457        assert!(result.is_err());
458    }
459
460    // ---------------------------------------------------------------
461    // get_key / get_optional_key
462    // ---------------------------------------------------------------
463
464    #[test]
465    fn get_key_found() {
466        let map = make_map(&[("x", Value::U32(42))]);
467        let val = map.get_key("x").unwrap();
468        assert_eq!(*val, Value::U32(42));
469    }
470
471    #[test]
472    fn get_key_not_found_errors() {
473        let map = make_map(&[("x", Value::U32(42))]);
474        assert!(map.get_key("y").is_err());
475    }
476
477    #[test]
478    fn get_optional_key_none_for_missing() {
479        let map = make_map(&[("x", Value::U32(42))]);
480        assert_eq!(map.get_optional_key("y"), None);
481    }
482
483    #[test]
484    fn get_optional_key_ignores_non_text_keys() {
485        let map: ValueMap = vec![(Value::U32(1), Value::U32(2))];
486        assert_eq!(map.get_optional_key("1"), None);
487    }
488
489    // ---------------------------------------------------------------
490    // remove_key / remove_optional_key
491    // ---------------------------------------------------------------
492
493    #[test]
494    fn remove_key_success() {
495        let mut map = make_map(&[("a", Value::U32(1)), ("b", Value::U32(2))]);
496        let removed = map.remove_key("a").unwrap();
497        assert_eq!(removed, Value::U32(1));
498        assert_eq!(map.len(), 1);
499    }
500
501    #[test]
502    fn remove_key_not_found_errors() {
503        let mut map = make_map(&[("a", Value::U32(1))]);
504        assert!(map.remove_key("missing").is_err());
505    }
506
507    #[test]
508    fn remove_optional_key_returns_none_for_missing() {
509        let mut map = make_map(&[("a", Value::U32(1))]);
510        assert_eq!(map.remove_optional_key("missing"), None);
511    }
512
513    #[test]
514    fn remove_optional_key_returns_value() {
515        let mut map = make_map(&[("a", Value::U32(1))]);
516        assert_eq!(map.remove_optional_key("a"), Some(Value::U32(1)));
517        assert!(map.is_empty());
518    }
519
520    // ---------------------------------------------------------------
521    // remove_optional_key_value
522    // ---------------------------------------------------------------
523
524    #[test]
525    fn remove_optional_key_value_by_value_key() {
526        let mut map: ValueMap = vec![
527            (Value::U32(10), Value::Bool(true)),
528            (text("x"), Value::Bool(false)),
529        ];
530        let removed = map.remove_optional_key_value(&Value::U32(10));
531        assert_eq!(removed, Some(Value::Bool(true)));
532        assert_eq!(map.len(), 1);
533    }
534
535    #[test]
536    fn remove_optional_key_value_not_found() {
537        let mut map = make_map(&[("a", Value::U32(1))]);
538        assert_eq!(map.remove_optional_key_value(&Value::U32(99)), None);
539    }
540
541    // ---------------------------------------------------------------
542    // insert_string_key_value
543    // ---------------------------------------------------------------
544
545    #[test]
546    fn insert_string_key_value_appends() {
547        let mut map: ValueMap = vec![];
548        map.insert_string_key_value("hello".to_string(), Value::Bool(true));
549        assert_eq!(map.len(), 1);
550        assert_eq!(map.get_optional_key("hello"), Some(&Value::Bool(true)));
551    }
552
553    // ---------------------------------------------------------------
554    // from_btree_map
555    // ---------------------------------------------------------------
556
557    #[test]
558    fn from_btree_map_preserves_entries() {
559        let mut btree = BTreeMap::new();
560        btree.insert("b".to_string(), Value::U32(2));
561        btree.insert("a".to_string(), Value::U32(1));
562        let map = ValueMap::from_btree_map(btree);
563        assert_eq!(map.len(), 2);
564        assert_eq!(map.get_optional_key("a"), Some(&Value::U32(1)));
565        assert_eq!(map.get_optional_key("b"), Some(&Value::U32(2)));
566    }
567
568    // ---------------------------------------------------------------
569    // get_key_by_value_mut_or_insert
570    // ---------------------------------------------------------------
571
572    #[test]
573    fn get_key_by_value_mut_or_insert_inserts_new() {
574        let mut map: ValueMap = vec![];
575        let val = map.get_key_by_value_mut_or_insert(&Value::U32(42), Value::Bool(true));
576        assert_eq!(*val, Value::Bool(true));
577        assert_eq!(map.len(), 1);
578    }
579
580    #[test]
581    fn get_key_by_value_mut_or_insert_returns_existing() {
582        let mut map: ValueMap = vec![(Value::U32(42), Value::Bool(false))];
583        let val = map.get_key_by_value_mut_or_insert(&Value::U32(42), Value::Bool(true));
584        assert_eq!(*val, Value::Bool(false));
585    }
586
587    // ---------------------------------------------------------------
588    // sort_by_keys_and_inner_maps
589    // ---------------------------------------------------------------
590
591    #[test]
592    fn sort_by_keys_and_inner_maps_sorts_recursively() {
593        let inner = make_map(&[("z", Value::U32(1)), ("a", Value::U32(2))]);
594        let mut map = make_map(&[("b", Value::Map(inner)), ("a", Value::U32(3))]);
595        map.sort_by_keys_and_inner_maps();
596        // Outer keys should be sorted
597        assert_eq!(map[0].0, text("a"));
598        assert_eq!(map[1].0, text("b"));
599        // Inner map should also be sorted
600        if let Value::Map(ref inner) = map[1].1 {
601            assert_eq!(inner[0].0, text("a"));
602            assert_eq!(inner[1].0, text("z"));
603        } else {
604            panic!("expected inner map");
605        }
606    }
607
608    // ---------------------------------------------------------------
609    // to_btree_ref_string_map
610    // ---------------------------------------------------------------
611
612    #[test]
613    fn to_btree_ref_string_map_valid() {
614        let val = Value::Map(make_map(&[("x", Value::U32(10))]));
615        let btree = val.to_btree_ref_string_map().unwrap();
616        assert_eq!(btree.get("x"), Some(&&Value::U32(10)));
617    }
618
619    #[test]
620    fn to_btree_ref_string_map_error_on_non_map() {
621        let val = Value::U32(1);
622        assert!(val.to_btree_ref_string_map().is_err());
623    }
624
625    #[test]
626    fn to_btree_ref_string_map_error_on_non_string_key() {
627        let val = Value::Map(vec![(Value::U32(1), Value::U32(2))]);
628        assert!(val.to_btree_ref_string_map().is_err());
629    }
630}
631
632impl Value {
633    /// If the `Value` is a `Map`, returns a the associated `BTreeMap<String, Value>` data as `Ok`.
634    /// Returns `Err(Error::Structure("reason"))` otherwise.
635    ///
636    /// ```
637    /// # use std::collections::BTreeMap;
638    /// # use platform_value::{Error, Value};
639    /// #
640    /// let mut value = Value::Map(
641    ///     vec![
642    ///         (Value::Text(String::from("key")), Value::Float(18.)),
643    ///     ]
644    /// );
645    /// assert_eq!(value.into_btree_string_map(), Ok(BTreeMap::from([(String::from("key"), Value::Float(18.))])));
646    ///
647    /// let value = Value::Bool(true);
648    /// assert_eq!(value.into_btree_string_map(), Err(Error::StructureError("value is not a map".to_string())))
649    /// ```
650    pub fn into_btree_string_map(self) -> Result<BTreeMap<String, Value>, Error> {
651        Self::map_into_btree_string_map(self.into_map()?)
652    }
653
654    /// If the `Value` is a `Map`, returns a the associated `BTreeMap<String, Value>` data as `Ok`.
655    /// Returns `Err(Error::Structure("reason"))` otherwise.
656    ///
657    /// ```
658    /// # use std::collections::BTreeMap;
659    /// # use platform_value::{Error, Value};
660    /// #
661    /// let mut value = Value::Map(
662    ///     vec![
663    ///         (Value::Text(String::from("key")), Value::Float(18.)),
664    ///     ]
665    /// );
666    /// assert_eq!(value.to_btree_ref_string_map(), Ok(BTreeMap::from([(String::from("key"), &Value::Float(18.))])));
667    ///
668    /// let value = Value::Bool(true);
669    /// assert_eq!(value.to_btree_ref_string_map(), Err(Error::StructureError("value is not a map".to_string())))
670    /// ```
671    pub fn to_btree_ref_string_map(&self) -> Result<BTreeMap<String, &Value>, Error> {
672        Self::map_ref_into_btree_string_map(self.to_map_ref()?)
673    }
674
675    /// If the `Value` is a `Map`, returns a the associated `BTreeMap<String, Value>` data as `Ok`.
676    /// Returns `Err(Error::Structure("reason"))` otherwise.
677    ///
678    /// ```
679    /// # use std::collections::BTreeMap;
680    /// # use platform_value::{Error, Value};
681    /// #
682    /// let mut value = Value::Map(
683    ///     vec![
684    ///         (Value::Text(String::from("key")), Value::Float(18.)),
685    ///     ]
686    /// );
687    /// assert_eq!(value.to_ref_string_map::<BTreeMap<_,_>>(), Ok(BTreeMap::from([(String::from("key"), &Value::Float(18.))])));
688    ///
689    /// assert_eq!(value.to_ref_string_map::<Vec<(_,_)>>(), Ok(vec![(String::from("key"), &Value::Float(18.))]));
690    ///
691    /// let value = Value::Bool(true);
692    /// assert_eq!(value.to_ref_string_map::<Vec<(_,_)>>(), Err(Error::StructureError("value is not a map".to_string())))
693    /// ```
694    pub fn to_ref_string_map<'a, I: FromIterator<(String, &'a Value)>>(
695        &'a self,
696    ) -> Result<I, Error> {
697        Self::map_ref_into_string_map(self.to_map_ref()?)
698    }
699
700    /// If the `Value` is a `Map`, returns a the associated `BTreeMap<String, Value>` data as `Ok`.
701    /// Returns `Err(Error::Structure("reason"))` otherwise.
702    ///
703    /// ```
704    /// # use std::collections::BTreeMap;
705    /// # use platform_value::{Error, Value};
706    /// #
707    /// let mut value = Value::Map(
708    ///     vec![
709    ///         (Value::Text(String::from("key")), Value::Float(18.)),
710    ///     ]
711    /// );
712    /// assert_eq!(value.to_ref_string_map_mut::<BTreeMap<_,_>>(), Ok(BTreeMap::from([(String::from("key"), &mut Value::Float(18.))])));
713    ///
714    /// assert_eq!(value.to_ref_string_map_mut::<Vec<(_,_)>>(), Ok(vec![(String::from("key"), &mut Value::Float(18.))]));
715    ///
716    /// let mut value = Value::Bool(true);
717    /// assert_eq!(value.to_ref_string_map_mut::<Vec<(_,_)>>(), Err(Error::StructureError("value is not a map".to_string())))
718    /// ```
719    pub fn to_ref_string_map_mut<'a, I: FromIterator<(String, &'a mut Value)>>(
720        &'a mut self,
721    ) -> Result<I, Error> {
722        Self::map_mut_ref_into_string_map(self.as_map_mut_ref()?)
723    }
724
725    /// Takes a ValueMap which is a `Vec<(Value, Value)>`
726    /// Returns a BTreeMap<String, Value> as long as each Key is a String
727    /// Returns `Err(Error::Structure("reason"))` otherwise.
728    pub fn map_into_btree_string_map(map: ValueMap) -> Result<BTreeMap<String, Value>, Error> {
729        map.into_iter()
730            .map(|(key, value)| {
731                let key = key
732                    .into_text()
733                    .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
734                Ok((key, value))
735            })
736            .collect::<Result<BTreeMap<String, Value>, Error>>()
737    }
738
739    /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>`
740    /// Returns a BTreeMap<String, &Value> as long as each Key is a String
741    /// Returns `Err(Error::Structure("reason"))` otherwise.
742    pub fn map_ref_into_btree_string_map(
743        map: &ValueMap,
744    ) -> Result<BTreeMap<String, &Value>, Error> {
745        map.iter()
746            .map(|(key, value)| {
747                let key = key
748                    .to_text()
749                    .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
750                Ok((key, value))
751            })
752            .collect::<Result<BTreeMap<String, &Value>, Error>>()
753    }
754
755    /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>`
756    /// Also takes a sort_key
757    /// Returns a IndexMap<String, &Value> as long as each Key is a String
758    /// The index map is in the order sorted by the sort key
759    /// The type T is the type of the value of the sort key
760    /// Returns `Err(Error::Structure("reason"))` otherwise.
761    pub fn map_ref_into_indexed_string_map<'a, T>(
762        map: &'a ValueMap,
763        sort_key: &str,
764    ) -> Result<IndexMap<String, &'a Value>, Error>
765    where
766        T: TryFrom<i128>
767            + TryFrom<u128>
768            + TryFrom<u64>
769            + TryFrom<i64>
770            + TryFrom<u32>
771            + TryFrom<i32>
772            + TryFrom<u16>
773            + TryFrom<i16>
774            + TryFrom<u8>
775            + TryFrom<i8>
776            + Ord,
777    {
778        // Check if the sort key exists in all values
779        for (_, value) in map.iter() {
780            value.get_integer::<T>(sort_key)?;
781        }
782
783        let mut sorted_map: Vec<_> = map.iter().collect();
784
785        sorted_map.sort_by(|(_, value_1), (_, value_2)| {
786            let pos_1: T = value_1.get_integer(sort_key).expect("expected sort key");
787            let pos_2: T = value_2.get_integer(sort_key).expect("expected sort key");
788            pos_1.cmp(&pos_2)
789        });
790
791        sorted_map
792            .into_iter()
793            .map(|(key, value)| {
794                let key = key
795                    .to_text()
796                    .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
797                Ok((key, value))
798            })
799            .collect::<Result<IndexMap<String, &Value>, Error>>()
800    }
801
802    /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>`
803    /// Returns a BTreeMap<String, &Value> as long as each Key is a String
804    /// Returns `Err(Error::Structure("reason"))` otherwise.
805    pub fn map_ref_into_string_map<'a, I: FromIterator<(String, &'a Value)>>(
806        map: &'a ValueMap,
807    ) -> Result<I, Error> {
808        map.iter()
809            .map(|(key, value)| {
810                let key = key
811                    .to_text()
812                    .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
813                Ok((key, value))
814            })
815            .collect::<Result<I, Error>>()
816    }
817
818    /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>`
819    /// Returns a BTreeMap<String, &Value> as long as each Key is a String
820    /// Returns `Err(Error::Structure("reason"))` otherwise.
821    pub fn map_mut_ref_into_string_map<'a, I: FromIterator<(String, &'a mut Value)>>(
822        map: &'a mut ValueMap,
823    ) -> Result<I, Error> {
824        map.iter_mut()
825            .map(|(key, value)| {
826                let key = key
827                    .to_text()
828                    .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
829                Ok((key, value))
830            })
831            .collect::<Result<I, Error>>()
832    }
833}