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 }
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}