jst/
obj.rs

1use std::{self, collections::HashMap, fmt, ops::Index};
2
3use crate::{Parser, ParserErr, Val};
4
5#[derive(PartialEq, Clone)]
6pub struct Obj(HashMap<String, Val>);
7
8impl Index<&str> for Obj {
9    type Output = Val;
10
11    fn index(&self, key: &str) -> &Val {
12        let r = self.get(key);
13        if let Some(v) = r {
14            v
15        } else {
16            &Val::Undef
17        }
18    }
19}
20
21// trait Json: fmt::Display + fmt::Debug {
22//     fn parse(str: &str) -> Result<Val, ParserErr>;
23//     fn new() -> Self;
24//     fn from_map(v: HashMap<String, Val>) -> Self;
25//     // fn len(&self) -> usize;
26//     // fn get(&self, key: &str) -> Option<&Val>;
27//     // fn get_mut(&mut self, key: &str) -> Option<&mut Val>;
28//     // fn set(&mut self, key: &str, val: Val) -> Option<Val>;
29//     // fn remove(&mut self, key: &str) -> Option<Val>;
30//     //fn index(&self, key: &str) -> &Val;
31// }
32
33impl Obj {
34    pub fn new() -> Self {
35        Obj(HashMap::new())
36    }
37
38    pub fn parse(str: &str) -> Result<Val, ParserErr> {
39        let mut parser = Parser::new(str);
40        parser.parse(true)
41    }
42
43    pub fn from_map(v: HashMap<String, Val>) -> Self {
44        Self(v)
45    }
46}
47
48impl Obj {
49    pub fn len(&self) -> usize {
50        self.0.len()
51    }
52
53    pub fn get(&self, key: &str) -> Option<&Val> {
54        self.0.get(key.into())
55    }
56
57    pub fn get_mut(&mut self, key: &str) -> Option<&mut Val> {
58        self.0.get_mut(key.into())
59    }
60
61    pub fn set(&mut self, key: &str, val: Val) -> Option<Val> {
62        self.0.insert(key.into(), val)
63    }
64
65    pub fn remove(&mut self, key: &str) -> Option<Val> {
66        self.0.remove(key.into())
67    }
68}
69
70impl IntoIterator for Obj {
71    type Item = (String, Val);
72    type IntoIter = <HashMap<String, Val> as IntoIterator>::IntoIter;
73
74    #[inline]
75    fn into_iter(self) -> Self::IntoIter {
76        self.0.into_iter()
77    }
78}
79
80
81impl fmt::Display for Obj {
82    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83        write!(f, "{:?}", self)
84    }
85}
86
87impl Extend<(String, Val)> for Obj {
88    fn extend<T: IntoIterator<Item = (String, Val)>>(&mut self, iter: T) {
89        self.0.extend(iter)
90    }
91}
92
93impl fmt::Debug for Obj {
94    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
95        if self.0.len() == 0 {
96            write!(f, "{{}}")
97        } else {
98            // map the key and value
99            // join the values with \n
100            // split into lines
101            // add an indentation for each line
102            // join and collect the result
103            let lines = self
104                .0
105                .iter()
106                .map(|(key, val)| format!("{:?}: {:?}", key, val))
107                .collect::<Vec<String>>()
108                .join(",\n")
109                .split("\n")
110                .map(|line| format!("    {}", line))
111                .collect::<Vec<String>>()
112                .join("\n");
113
114            write!(f, "{{\n{}\n}}", lines)
115        }
116    }
117}