Skip to main content

viperus/
map.rs

1use std::collections::hash_map::Drain;
2use std::collections::HashMap;
3
4
5mod map_value;
6pub use map_value::ViperusValue;
7
8#[derive(Debug)]
9pub struct Map {
10    data: HashMap<String, ViperusValue>,
11}
12
13
14impl Default for Map { fn default() -> Self {Map::new()  } }   
15
16impl Map {
17    pub fn new() -> Self {
18        Map {
19            data: HashMap::new(),
20        }
21    }
22
23
24    pub fn drain<'a>(&'a mut self) -> Drain<'a,String,ViperusValue>
25     
26    {
27      self.data.drain()
28    }
29
30    pub fn add<T>(&mut self, key: &str, value: T) -> Option<T>
31    where
32        ViperusValue: From<T>,
33        ViperusValue: Into<T>,
34    {
35        match self.data.insert(key.to_string(), ViperusValue::from(value)) {
36            None => None,
37            Some(mv) => Some(mv.into()),
38        }
39    }
40
41    pub fn add_value(&mut self, key: &str, value: ViperusValue) -> Option<ViperusValue> {
42        self.data.insert(key.to_string(), value)
43        //     let path: Vec<&str>=key.to_lowercase().split(".").collect();
44        //     let pathLen = path.len();
45        //    for pi  in 0..pathLen-1 {
46        //        let v = self.data.get(path[pi]);
47        //        if let None = v {
48        //            let node=
49
50        //        }
51
52        //    }
53
54        //     todo!("imlp add a key to the map")
55    }
56
57    pub fn get_value(&self, key: &str) -> Option<&ViperusValue> {
58        self.data.get(key)
59    }
60
61    pub fn get<'a,'b,'c, T>(&'a self, key: &'a str) -> Option<T>
62    where
63        ViperusValue: From<T>,
64        &'c ViperusValue: Into<T>,
65        ViperusValue: Into<T>,
66         
67    {
68        match self.data.get(key) {
69            None => None,
70            Some(mv) => Some((*mv).clone().into()),
71        }
72    }
73
74     
75
76
77    pub fn merge(&mut self, src: &Map)  {
78         
79        for (k,v) in &src.data {
80
81            self.add_value(k, v.clone());
82
83        }
84
85    }
86
87
88}
89
90#[cfg(test)]
91mod tests {
92    use super::*;
93    #[test]
94    fn test_map_add_get() {
95        let mut m = Map::new();
96        let mv0 = m.add_value("test.value", ViperusValue::I32(10));
97        assert_eq!(None, mv0);
98        let mv1 = m.get_value("test.value").unwrap();
99        if let ViperusValue::I32(v1) = mv1 {
100            assert_eq!(10, *v1);
101        }  
102    }
103
104    #[test]
105    fn test_map_get_32() {
106        let mut m = Map::default();
107        m.add_value("test.value2", ViperusValue::from("none"));
108
109        let mv0 = m.add_value("test.value", ViperusValue::from(42));
110        assert_eq!(None, mv0);
111      
112        let _a1 = m.add::<i32>("test.value_i32", 314).unwrap_or_default();
113        let _a2 = m.add::<i32>("test.value_i32", 314).unwrap_or_default();
114        
115        let v1 = m.get::<i32>("test.value").unwrap();
116        assert_eq!(42, v1);
117
118        let v1_i32 = m.get::<i32>("test.value_i32").unwrap();
119        assert_eq!(314, v1_i32);
120
121         
122        let v1_str = m.get::<String>("test.value2").unwrap();
123        assert_eq!("none", v1_str);
124
125        
126        
127    }
128    #[test]
129    #[should_panic]
130    fn invalid_map_get_32() {
131        let mut m = Map::default();
132        m.add_value("test.value2", ViperusValue::from("none"));
133
134        assert!(m.get::<i32>("test.value2").is_none())
135     
136    }
137}