1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use crate::list::list_to_string;
use crate::molt_err;
use crate::molt_ok;
use crate::types::Exception;
use crate::types::MoltDict;
use crate::types::MoltList;
use crate::types::MoltResult;
use crate::value::Value;
use indexmap::IndexMap;
pub fn dict_new() -> MoltDict {
IndexMap::new()
}
pub(crate) fn dict_path_insert(dict_val: &Value, keys: &[Value], value: &Value) -> MoltResult {
assert!(!keys.is_empty());
let dict = dict_val.as_dict()?;
if keys.len() == 1 {
molt_ok!(dict_insert(&*dict, &keys[0], &value))
} else if let Some(dval) = dict.get(&keys[0]) {
molt_ok!(dict_insert(
&*dict,
&keys[0],
&dict_path_insert(dval, &keys[1..], value)?
))
} else {
let dval = Value::from(dict_new());
molt_ok!(dict_insert(
&*dict,
&keys[0],
&dict_path_insert(&dval, &keys[1..], value)?
))
}
}
pub(crate) fn dict_insert(dict: &MoltDict, key: &Value, value: &Value) -> MoltDict {
let mut new_dict = dict.clone();
new_dict.insert(key.clone(), value.clone());
new_dict
}
pub(crate) fn dict_path_remove(dict_val: &Value, keys: &[Value]) -> MoltResult {
assert!(!keys.is_empty());
let dict = dict_val.as_dict()?;
if keys.len() == 1 {
molt_ok!(dict_remove(&*dict, &keys[0]))
} else if let Some(dval) = dict.get(&keys[0]) {
molt_ok!(dict_insert(
&*dict,
&keys[0],
&dict_path_remove(dval, &keys[1..])?
))
} else {
molt_err!("key \"{}\" not known in dictionary", keys[0])
}
}
pub(crate) fn dict_remove(dict: &MoltDict, key: &Value) -> MoltDict {
let mut new_dict = dict.clone();
new_dict.shift_remove(key);
new_dict
}
pub(crate) fn dict_to_string(dict: &MoltDict) -> String {
let mut vec: MoltList = Vec::new();
for (k, v) in dict {
vec.push(k.clone());
vec.push(v.clone());
}
list_to_string(&vec)
}
pub(crate) fn list_to_dict(list: &[Value]) -> MoltDict {
assert!(list.len() % 2 == 0);
let mut dict = dict_new();
for i in (0..list.len()).step_by(2) {
dict.insert(list[i].clone(), list[i + 1].clone());
}
dict
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::MoltDict;
#[test]
fn test_dict_to_string() {
let mut dict: MoltDict = dict_new();
assert_eq!(dict_to_string(&dict), "");
dict.insert("abc".into(), "123".into());
assert_eq!(dict_to_string(&dict), "abc 123");
}
}