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)]
227mod tests {
228    use super::*;
229
230    fn text(s: &str) -> Value {
231        Value::Text(s.to_string())
232    }
233
234    fn make_map(pairs: &[(&str, Value)]) -> ValueMap {
235        pairs.iter().map(|(k, v)| (text(k), v.clone())).collect()
236    }
237
238    // ---------------------------------------------------------------
239    // sort_by_keys
240    // ---------------------------------------------------------------
241
242    #[test]
243    fn sort_by_keys_mixed_text_keys() {
244        let mut map = make_map(&[
245            ("c", Value::U32(3)),
246            ("a", Value::U32(1)),
247            ("b", Value::U32(2)),
248        ]);
249        map.sort_by_keys();
250        let keys: Vec<_> = map.iter().map(|(k, _)| k.clone()).collect();
251        assert_eq!(keys, vec![text("a"), text("b"), text("c")]);
252    }
253
254    #[test]
255    fn sort_by_keys_mixed_types() {
256        // Integer keys should sort before text keys via PartialOrd on Value
257        let mut map: ValueMap = vec![
258            (text("z"), Value::U32(1)),
259            (Value::U32(5), Value::U32(2)),
260            (text("a"), Value::U32(3)),
261        ];
262        map.sort_by_keys();
263        // U32(5) < Text("a") < Text("z") by Value's PartialOrd (enum variant order)
264        assert_eq!(map[0].0, Value::U32(5));
265        assert_eq!(map[1].0, text("a"));
266        assert_eq!(map[2].0, text("z"));
267    }
268
269    // ---------------------------------------------------------------
270    // sort_by_lexicographical_byte_ordering_keys
271    // ---------------------------------------------------------------
272
273    #[test]
274    fn sort_by_lexicographical_byte_ordering_shorter_first() {
275        // "ab" (len 2) should come before "abc" (len 3)
276        let mut map = make_map(&[
277            ("abc", Value::U32(1)),
278            ("ab", Value::U32(2)),
279            ("a", Value::U32(3)),
280        ]);
281        map.sort_by_lexicographical_byte_ordering_keys();
282        let keys: Vec<_> = map.iter().map(|(k, _)| k.to_text().unwrap()).collect();
283        assert_eq!(keys, vec!["a", "ab", "abc"]);
284    }
285
286    #[test]
287    fn sort_by_lexicographical_byte_ordering_same_length_alphabetical() {
288        let mut map = make_map(&[
289            ("cb", Value::U32(1)),
290            ("ab", Value::U32(2)),
291            ("bb", Value::U32(3)),
292        ]);
293        map.sort_by_lexicographical_byte_ordering_keys();
294        let keys: Vec<_> = map.iter().map(|(k, _)| k.to_text().unwrap()).collect();
295        assert_eq!(keys, vec!["ab", "bb", "cb"]);
296    }
297
298    #[test]
299    fn sort_by_lexicographical_byte_ordering_non_text_keys_uses_partial_cmp() {
300        let mut map: ValueMap = vec![(Value::U32(10), Value::Null), (Value::U32(2), Value::Null)];
301        map.sort_by_lexicographical_byte_ordering_keys();
302        assert_eq!(map[0].0, Value::U32(2));
303        assert_eq!(map[1].0, Value::U32(10));
304    }
305
306    // ---------------------------------------------------------------
307    // get_key_mut_or_insert
308    // ---------------------------------------------------------------
309
310    #[test]
311    fn get_key_mut_or_insert_inserts_new() {
312        let mut map = make_map(&[("a", Value::U32(1))]);
313        let val = map.get_key_mut_or_insert("b", Value::U32(99));
314        assert_eq!(*val, Value::U32(99));
315        // Mutate the returned reference
316        *val = Value::U32(100);
317        assert_eq!(map.get_optional_key("b"), Some(&Value::U32(100)));
318    }
319
320    #[test]
321    fn get_key_mut_or_insert_returns_existing() {
322        let mut map = make_map(&[("a", Value::U32(1))]);
323        let val = map.get_key_mut_or_insert("a", Value::U32(99));
324        // Should return existing value, not the default
325        assert_eq!(*val, Value::U32(1));
326    }
327
328    #[test]
329    fn get_key_mut_or_insert_existing_is_mutable() {
330        let mut map = make_map(&[("a", Value::U32(1))]);
331        let val = map.get_key_mut_or_insert("a", Value::U32(99));
332        *val = Value::U32(42);
333        assert_eq!(map.get_optional_key("a"), Some(&Value::U32(42)));
334    }
335
336    // ---------------------------------------------------------------
337    // remove_optional_key_if_null
338    // ---------------------------------------------------------------
339
340    #[test]
341    fn remove_optional_key_if_null_removes_null() {
342        let mut map = make_map(&[("a", Value::Null), ("b", Value::U32(2))]);
343        map.remove_optional_key_if_null("a");
344        assert_eq!(map.get_optional_key("a"), None);
345        assert_eq!(map.get_optional_key("b"), Some(&Value::U32(2)));
346    }
347
348    #[test]
349    fn remove_optional_key_if_null_keeps_non_null() {
350        let mut map = make_map(&[("a", Value::U32(1))]);
351        map.remove_optional_key_if_null("a");
352        assert_eq!(map.get_optional_key("a"), Some(&Value::U32(1)));
353    }
354
355    #[test]
356    fn remove_optional_key_if_null_missing_key_is_noop() {
357        let mut map = make_map(&[("a", Value::U32(1))]);
358        map.remove_optional_key_if_null("missing");
359        assert_eq!(map.len(), 1);
360    }
361
362    // ---------------------------------------------------------------
363    // remove_optional_key_if_empty_array
364    // ---------------------------------------------------------------
365
366    #[test]
367    fn remove_optional_key_if_empty_array_removes_empty() {
368        let mut map = make_map(&[("a", Value::Array(vec![])), ("b", Value::U32(1))]);
369        map.remove_optional_key_if_empty_array("a");
370        assert_eq!(map.get_optional_key("a"), None);
371        assert_eq!(map.get_optional_key("b"), Some(&Value::U32(1)));
372    }
373
374    #[test]
375    fn remove_optional_key_if_empty_array_keeps_non_empty() {
376        let mut map = make_map(&[("a", Value::Array(vec![Value::U32(1)]))]);
377        map.remove_optional_key_if_empty_array("a");
378        assert!(map.get_optional_key("a").is_some());
379    }
380
381    #[test]
382    fn remove_optional_key_if_empty_array_keeps_non_array() {
383        let mut map = make_map(&[("a", Value::U32(42))]);
384        map.remove_optional_key_if_empty_array("a");
385        assert_eq!(map.get_optional_key("a"), Some(&Value::U32(42)));
386    }
387
388    #[test]
389    fn remove_optional_key_if_empty_array_missing_key_is_noop() {
390        let mut map = make_map(&[("a", Value::U32(1))]);
391        map.remove_optional_key_if_empty_array("missing");
392        assert_eq!(map.len(), 1);
393    }
394
395    // ---------------------------------------------------------------
396    // into_btree_string_map
397    // ---------------------------------------------------------------
398
399    #[test]
400    fn into_btree_string_map_valid_conversion() {
401        let val = Value::Map(make_map(&[("b", Value::U32(2)), ("a", Value::U32(1))]));
402        let btree = val.into_btree_string_map().unwrap();
403        assert_eq!(btree.get("a"), Some(&Value::U32(1)));
404        assert_eq!(btree.get("b"), Some(&Value::U32(2)));
405        // BTreeMap should be sorted by key
406        let keys: Vec<_> = btree.keys().collect();
407        assert_eq!(keys, vec!["a", "b"]);
408    }
409
410    #[test]
411    fn into_btree_string_map_error_on_non_string_keys() {
412        let val = Value::Map(vec![(Value::U32(1), Value::U32(2))]);
413        let result = val.into_btree_string_map();
414        assert!(result.is_err());
415    }
416
417    #[test]
418    fn into_btree_string_map_error_on_non_map() {
419        let val = Value::Bool(true);
420        let result = val.into_btree_string_map();
421        assert!(result.is_err());
422    }
423
424    // ---------------------------------------------------------------
425    // map_ref_into_indexed_string_map
426    // ---------------------------------------------------------------
427
428    #[test]
429    fn map_ref_into_indexed_string_map_sorts_by_integer_key() {
430        let map: ValueMap = vec![
431            (
432                text("second"),
433                Value::Map(make_map(&[("pos", Value::U32(2))])),
434            ),
435            (
436                text("first"),
437                Value::Map(make_map(&[("pos", Value::U32(1))])),
438            ),
439            (
440                text("third"),
441                Value::Map(make_map(&[("pos", Value::U32(3))])),
442            ),
443        ];
444        let indexed = Value::map_ref_into_indexed_string_map::<u32>(&map, "pos").unwrap();
445        let keys: Vec<_> = indexed.keys().collect();
446        assert_eq!(keys, vec!["first", "second", "third"]);
447    }
448
449    #[test]
450    fn map_ref_into_indexed_string_map_error_missing_sort_key() {
451        let map: ValueMap = vec![(
452            text("item"),
453            Value::Map(make_map(&[("other", Value::U32(1))])),
454        )];
455        let result = Value::map_ref_into_indexed_string_map::<u32>(&map, "pos");
456        assert!(result.is_err());
457    }
458
459    // ---------------------------------------------------------------
460    // get_key / get_optional_key
461    // ---------------------------------------------------------------
462
463    #[test]
464    fn get_key_found() {
465        let map = make_map(&[("x", Value::U32(42))]);
466        let val = map.get_key("x").unwrap();
467        assert_eq!(*val, Value::U32(42));
468    }
469
470    #[test]
471    fn get_key_not_found_errors() {
472        let map = make_map(&[("x", Value::U32(42))]);
473        assert!(map.get_key("y").is_err());
474    }
475
476    #[test]
477    fn get_optional_key_none_for_missing() {
478        let map = make_map(&[("x", Value::U32(42))]);
479        assert_eq!(map.get_optional_key("y"), None);
480    }
481
482    #[test]
483    fn get_optional_key_ignores_non_text_keys() {
484        let map: ValueMap = vec![(Value::U32(1), Value::U32(2))];
485        assert_eq!(map.get_optional_key("1"), None);
486    }
487
488    // ---------------------------------------------------------------
489    // remove_key / remove_optional_key
490    // ---------------------------------------------------------------
491
492    #[test]
493    fn remove_key_success() {
494        let mut map = make_map(&[("a", Value::U32(1)), ("b", Value::U32(2))]);
495        let removed = map.remove_key("a").unwrap();
496        assert_eq!(removed, Value::U32(1));
497        assert_eq!(map.len(), 1);
498    }
499
500    #[test]
501    fn remove_key_not_found_errors() {
502        let mut map = make_map(&[("a", Value::U32(1))]);
503        assert!(map.remove_key("missing").is_err());
504    }
505
506    #[test]
507    fn remove_optional_key_returns_none_for_missing() {
508        let mut map = make_map(&[("a", Value::U32(1))]);
509        assert_eq!(map.remove_optional_key("missing"), None);
510    }
511
512    #[test]
513    fn remove_optional_key_returns_value() {
514        let mut map = make_map(&[("a", Value::U32(1))]);
515        assert_eq!(map.remove_optional_key("a"), Some(Value::U32(1)));
516        assert!(map.is_empty());
517    }
518
519    // ---------------------------------------------------------------
520    // remove_optional_key_value
521    // ---------------------------------------------------------------
522
523    #[test]
524    fn remove_optional_key_value_by_value_key() {
525        let mut map: ValueMap = vec![
526            (Value::U32(10), Value::Bool(true)),
527            (text("x"), Value::Bool(false)),
528        ];
529        let removed = map.remove_optional_key_value(&Value::U32(10));
530        assert_eq!(removed, Some(Value::Bool(true)));
531        assert_eq!(map.len(), 1);
532    }
533
534    #[test]
535    fn remove_optional_key_value_not_found() {
536        let mut map = make_map(&[("a", Value::U32(1))]);
537        assert_eq!(map.remove_optional_key_value(&Value::U32(99)), None);
538    }
539
540    // ---------------------------------------------------------------
541    // insert_string_key_value
542    // ---------------------------------------------------------------
543
544    #[test]
545    fn insert_string_key_value_appends() {
546        let mut map: ValueMap = vec![];
547        map.insert_string_key_value("hello".to_string(), Value::Bool(true));
548        assert_eq!(map.len(), 1);
549        assert_eq!(map.get_optional_key("hello"), Some(&Value::Bool(true)));
550    }
551
552    // ---------------------------------------------------------------
553    // from_btree_map
554    // ---------------------------------------------------------------
555
556    #[test]
557    fn from_btree_map_preserves_entries() {
558        let mut btree = BTreeMap::new();
559        btree.insert("b".to_string(), Value::U32(2));
560        btree.insert("a".to_string(), Value::U32(1));
561        let map = ValueMap::from_btree_map(btree);
562        assert_eq!(map.len(), 2);
563        assert_eq!(map.get_optional_key("a"), Some(&Value::U32(1)));
564        assert_eq!(map.get_optional_key("b"), Some(&Value::U32(2)));
565    }
566
567    // ---------------------------------------------------------------
568    // get_key_by_value_mut_or_insert
569    // ---------------------------------------------------------------
570
571    #[test]
572    fn get_key_by_value_mut_or_insert_inserts_new() {
573        let mut map: ValueMap = vec![];
574        let val = map.get_key_by_value_mut_or_insert(&Value::U32(42), Value::Bool(true));
575        assert_eq!(*val, Value::Bool(true));
576        assert_eq!(map.len(), 1);
577    }
578
579    #[test]
580    fn get_key_by_value_mut_or_insert_returns_existing() {
581        let mut map: ValueMap = vec![(Value::U32(42), Value::Bool(false))];
582        let val = map.get_key_by_value_mut_or_insert(&Value::U32(42), Value::Bool(true));
583        assert_eq!(*val, Value::Bool(false));
584    }
585
586    // ---------------------------------------------------------------
587    // sort_by_keys_and_inner_maps
588    // ---------------------------------------------------------------
589
590    #[test]
591    fn sort_by_keys_and_inner_maps_sorts_recursively() {
592        let inner = make_map(&[("z", Value::U32(1)), ("a", Value::U32(2))]);
593        let mut map = make_map(&[("b", Value::Map(inner)), ("a", Value::U32(3))]);
594        map.sort_by_keys_and_inner_maps();
595        // Outer keys should be sorted
596        assert_eq!(map[0].0, text("a"));
597        assert_eq!(map[1].0, text("b"));
598        // Inner map should also be sorted
599        if let Value::Map(ref inner) = map[1].1 {
600            assert_eq!(inner[0].0, text("a"));
601            assert_eq!(inner[1].0, text("z"));
602        } else {
603            panic!("expected inner map");
604        }
605    }
606
607    // ---------------------------------------------------------------
608    // to_btree_ref_string_map
609    // ---------------------------------------------------------------
610
611    #[test]
612    fn to_btree_ref_string_map_valid() {
613        let val = Value::Map(make_map(&[("x", Value::U32(10))]));
614        let btree = val.to_btree_ref_string_map().unwrap();
615        assert_eq!(btree.get("x"), Some(&&Value::U32(10)));
616    }
617
618    #[test]
619    fn to_btree_ref_string_map_error_on_non_map() {
620        let val = Value::U32(1);
621        assert!(val.to_btree_ref_string_map().is_err());
622    }
623
624    #[test]
625    fn to_btree_ref_string_map_error_on_non_string_key() {
626        let val = Value::Map(vec![(Value::U32(1), Value::U32(2))]);
627        assert!(val.to_btree_ref_string_map().is_err());
628    }
629}
630
631impl Value {
632    /// If the `Value` is a `Map`, returns a the associated `BTreeMap<String, Value>` data as `Ok`.
633    /// Returns `Err(Error::Structure("reason"))` otherwise.
634    ///
635    /// ```
636    /// # use std::collections::BTreeMap;
637    /// # use platform_value::{Error, Value};
638    /// #
639    /// let mut value = Value::Map(
640    ///     vec![
641    ///         (Value::Text(String::from("key")), Value::Float(18.)),
642    ///     ]
643    /// );
644    /// assert_eq!(value.into_btree_string_map(), Ok(BTreeMap::from([(String::from("key"), Value::Float(18.))])));
645    ///
646    /// let value = Value::Bool(true);
647    /// assert_eq!(value.into_btree_string_map(), Err(Error::StructureError("value is not a map".to_string())))
648    /// ```
649    pub fn into_btree_string_map(self) -> Result<BTreeMap<String, Value>, Error> {
650        Self::map_into_btree_string_map(self.into_map()?)
651    }
652
653    /// If the `Value` is a `Map`, returns a the associated `BTreeMap<String, Value>` data as `Ok`.
654    /// Returns `Err(Error::Structure("reason"))` otherwise.
655    ///
656    /// ```
657    /// # use std::collections::BTreeMap;
658    /// # use platform_value::{Error, Value};
659    /// #
660    /// let mut value = Value::Map(
661    ///     vec![
662    ///         (Value::Text(String::from("key")), Value::Float(18.)),
663    ///     ]
664    /// );
665    /// assert_eq!(value.to_btree_ref_string_map(), Ok(BTreeMap::from([(String::from("key"), &Value::Float(18.))])));
666    ///
667    /// let value = Value::Bool(true);
668    /// assert_eq!(value.to_btree_ref_string_map(), Err(Error::StructureError("value is not a map".to_string())))
669    /// ```
670    pub fn to_btree_ref_string_map(&self) -> Result<BTreeMap<String, &Value>, Error> {
671        Self::map_ref_into_btree_string_map(self.to_map_ref()?)
672    }
673
674    /// If the `Value` is a `Map`, returns a the associated `BTreeMap<String, Value>` data as `Ok`.
675    /// Returns `Err(Error::Structure("reason"))` otherwise.
676    ///
677    /// ```
678    /// # use std::collections::BTreeMap;
679    /// # use platform_value::{Error, Value};
680    /// #
681    /// let mut value = Value::Map(
682    ///     vec![
683    ///         (Value::Text(String::from("key")), Value::Float(18.)),
684    ///     ]
685    /// );
686    /// assert_eq!(value.to_ref_string_map::<BTreeMap<_,_>>(), Ok(BTreeMap::from([(String::from("key"), &Value::Float(18.))])));
687    ///
688    /// assert_eq!(value.to_ref_string_map::<Vec<(_,_)>>(), Ok(vec![(String::from("key"), &Value::Float(18.))]));
689    ///
690    /// let value = Value::Bool(true);
691    /// assert_eq!(value.to_ref_string_map::<Vec<(_,_)>>(), Err(Error::StructureError("value is not a map".to_string())))
692    /// ```
693    pub fn to_ref_string_map<'a, I: FromIterator<(String, &'a Value)>>(
694        &'a self,
695    ) -> Result<I, Error> {
696        Self::map_ref_into_string_map(self.to_map_ref()?)
697    }
698
699    /// If the `Value` is a `Map`, returns a the associated `BTreeMap<String, Value>` data as `Ok`.
700    /// Returns `Err(Error::Structure("reason"))` otherwise.
701    ///
702    /// ```
703    /// # use std::collections::BTreeMap;
704    /// # use platform_value::{Error, Value};
705    /// #
706    /// let mut value = Value::Map(
707    ///     vec![
708    ///         (Value::Text(String::from("key")), Value::Float(18.)),
709    ///     ]
710    /// );
711    /// assert_eq!(value.to_ref_string_map_mut::<BTreeMap<_,_>>(), Ok(BTreeMap::from([(String::from("key"), &mut Value::Float(18.))])));
712    ///
713    /// assert_eq!(value.to_ref_string_map_mut::<Vec<(_,_)>>(), Ok(vec![(String::from("key"), &mut Value::Float(18.))]));
714    ///
715    /// let mut value = Value::Bool(true);
716    /// assert_eq!(value.to_ref_string_map_mut::<Vec<(_,_)>>(), Err(Error::StructureError("value is not a map".to_string())))
717    /// ```
718    pub fn to_ref_string_map_mut<'a, I: FromIterator<(String, &'a mut Value)>>(
719        &'a mut self,
720    ) -> Result<I, Error> {
721        Self::map_mut_ref_into_string_map(self.as_map_mut_ref()?)
722    }
723
724    /// Takes a ValueMap which is a `Vec<(Value, Value)>`
725    /// Returns a BTreeMap<String, Value> as long as each Key is a String
726    /// Returns `Err(Error::Structure("reason"))` otherwise.
727    pub fn map_into_btree_string_map(map: ValueMap) -> Result<BTreeMap<String, Value>, Error> {
728        map.into_iter()
729            .map(|(key, value)| {
730                let key = key
731                    .into_text()
732                    .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
733                Ok((key, value))
734            })
735            .collect::<Result<BTreeMap<String, Value>, Error>>()
736    }
737
738    /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>`
739    /// Returns a BTreeMap<String, &Value> as long as each Key is a String
740    /// Returns `Err(Error::Structure("reason"))` otherwise.
741    pub fn map_ref_into_btree_string_map(
742        map: &ValueMap,
743    ) -> Result<BTreeMap<String, &Value>, Error> {
744        map.iter()
745            .map(|(key, value)| {
746                let key = key
747                    .to_text()
748                    .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
749                Ok((key, value))
750            })
751            .collect::<Result<BTreeMap<String, &Value>, Error>>()
752    }
753
754    /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>`
755    /// Also takes a sort_key
756    /// Returns a IndexMap<String, &Value> as long as each Key is a String
757    /// The index map is in the order sorted by the sort key
758    /// The type T is the type of the value of the sort key
759    /// Returns `Err(Error::Structure("reason"))` otherwise.
760    pub fn map_ref_into_indexed_string_map<'a, T>(
761        map: &'a ValueMap,
762        sort_key: &str,
763    ) -> Result<IndexMap<String, &'a Value>, Error>
764    where
765        T: TryFrom<i128>
766            + TryFrom<u128>
767            + TryFrom<u64>
768            + TryFrom<i64>
769            + TryFrom<u32>
770            + TryFrom<i32>
771            + TryFrom<u16>
772            + TryFrom<i16>
773            + TryFrom<u8>
774            + TryFrom<i8>
775            + Ord,
776    {
777        // Check if the sort key exists in all values
778        for (_, value) in map.iter() {
779            value.get_integer::<T>(sort_key)?;
780        }
781
782        let mut sorted_map: Vec<_> = map.iter().collect();
783
784        sorted_map.sort_by(|(_, value_1), (_, value_2)| {
785            let pos_1: T = value_1.get_integer(sort_key).expect("expected sort key");
786            let pos_2: T = value_2.get_integer(sort_key).expect("expected sort key");
787            pos_1.cmp(&pos_2)
788        });
789
790        sorted_map
791            .into_iter()
792            .map(|(key, value)| {
793                let key = key
794                    .to_text()
795                    .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
796                Ok((key, value))
797            })
798            .collect::<Result<IndexMap<String, &Value>, Error>>()
799    }
800
801    /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>`
802    /// Returns a BTreeMap<String, &Value> as long as each Key is a String
803    /// Returns `Err(Error::Structure("reason"))` otherwise.
804    pub fn map_ref_into_string_map<'a, I: FromIterator<(String, &'a Value)>>(
805        map: &'a ValueMap,
806    ) -> Result<I, Error> {
807        map.iter()
808            .map(|(key, value)| {
809                let key = key
810                    .to_text()
811                    .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
812                Ok((key, value))
813            })
814            .collect::<Result<I, Error>>()
815    }
816
817    /// Takes a ref to a ValueMap which is a `&Vec<(Value, Value)>`
818    /// Returns a BTreeMap<String, &Value> as long as each Key is a String
819    /// Returns `Err(Error::Structure("reason"))` otherwise.
820    pub fn map_mut_ref_into_string_map<'a, I: FromIterator<(String, &'a mut Value)>>(
821        map: &'a mut ValueMap,
822    ) -> Result<I, Error> {
823        map.iter_mut()
824            .map(|(key, value)| {
825                let key = key
826                    .to_text()
827                    .map_err(|_| Error::StructureError("expected key to be string".to_string()))?;
828                Ok((key, value))
829            })
830            .collect::<Result<I, Error>>()
831    }
832}