platform_value/btreemap_extensions/
btreemap_path_insertion_extensions.rs

1use crate::value_map::{ValueMap, ValueMapHelper};
2use crate::{Error, Value};
3use std::collections::BTreeMap;
4
5pub trait BTreeValueMapInsertionPathHelper {
6    fn insert_at_path(&mut self, path: &str, value: Value) -> Result<(), Error>;
7}
8
9impl BTreeValueMapInsertionPathHelper for BTreeMap<String, Value> {
10    fn insert_at_path(&mut self, path: &str, value: Value) -> Result<(), Error> {
11        let mut split = path.split('.').peekable();
12        let first = split.next();
13        let Some(first_path_component) = first else {
14            return Err(Error::PathError("path was empty".to_string()));
15        };
16        if split.peek().is_none() {
17            self.insert(first_path_component.to_string(), value);
18        } else {
19            let mut current_value = self
20                .entry(first_path_component.to_string())
21                .or_insert(Value::Map(ValueMap::new()));
22            let mut last_path_component = None;
23            while let Some(path_component) = split.next() {
24                if split.peek().is_some() {
25                    let map = current_value.as_map_mut_ref()?;
26                    current_value =
27                        map.get_key_mut_or_insert(path_component, Value::Map(ValueMap::new()));
28                } else {
29                    last_path_component = Some(path_component)
30                }
31            }
32            if let Some(last_path_component) = last_path_component {
33                let map = current_value.as_map_mut_ref()?;
34                if let Some(new_value) = map.get_optional_key_mut(last_path_component) {
35                    *new_value = value;
36                } else {
37                    map.push((Value::Text(last_path_component.to_string()), value));
38                }
39            }
40        }
41
42        Ok(())
43    }
44}