1use std::ops::{Deref, DerefMut};
2use std::ops::{Index, IndexMut};
3use imbl::HashMap;
4use serde::{Deserialize, Serialize, Deserializer, Serializer};
5use serde_json::Value;
6#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct Attrs {
10 pub attrs: HashMap<String, Value>,
11}
12
13impl Serialize for Attrs {
14 fn serialize<S>(
15 &self,
16 serializer: S,
17 ) -> Result<S::Ok, S::Error>
18 where
19 S: Serializer,
20 {
21 self.attrs.serialize(serializer)
22 }
23}
24
25impl<'de> Deserialize<'de> for Attrs {
26 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
27 where
28 D: Deserializer<'de>,
29 {
30 let map = HashMap::<String, Value>::deserialize(deserializer)?;
31 Ok(Attrs { attrs: map })
32 }
33}
34
35impl Default for Attrs {
36 fn default() -> Self {
37 Self { attrs: HashMap::new() }
38 }
39}
40
41impl Index<&str> for Attrs {
42 type Output = Value;
43
44 fn index(
45 &self,
46 key: &str,
47 ) -> &Self::Output {
48 self.get_safe(key).expect("Key not found")
49 }
50}
51
52impl IndexMut<&str> for Attrs {
54 fn index_mut(
55 &mut self,
56 key: &str,
57 ) -> &mut Self::Output {
58 if !self.attrs.contains_key(key) {
59 self.attrs.insert(key.to_string(), Value::Null);
60 }
61 self.attrs.get_mut(key).expect("Key not found")
62 }
63}
64
65impl Attrs {
66 pub fn from(new_values: HashMap<String, Value>) -> Self {
67 Self { attrs: new_values }
68 }
69 pub fn get_value<T: serde::de::DeserializeOwned>(
70 &self,
71 key: &str,
72 ) -> Option<T> {
73 self.attrs.get(key).and_then(|v| serde_json::from_value(v.clone()).ok())
74 }
75 pub fn update(
76 &self,
77 new_values: HashMap<String, Value>,
78 ) -> Self {
79 let mut attrs = self.attrs.clone();
80 for (key, value) in new_values {
81 attrs.insert(key, value);
82 }
83 Attrs { attrs }
84 }
85 pub fn get_safe(
86 &self,
87 key: &str,
88 ) -> Option<&Value> {
89 self.attrs.get(key)
90 }
91}
92
93impl Deref for Attrs {
94 type Target = HashMap<String, Value>;
95
96 fn deref(&self) -> &Self::Target {
97 &self.attrs
98 }
99}
100
101impl DerefMut for Attrs {
102 fn deref_mut(&mut self) -> &mut Self::Target {
103 &mut self.attrs
104 }
105}