1use std::ops::{Deref, DerefMut};
2use std::ops::{Index, IndexMut};
3use im::HashMap;
4use serde::{Deserialize, Serialize, Deserializer, Serializer};
5use serde_json::Value;
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
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}
106
107#[derive(Debug, Clone, PartialEq, Eq, Hash)]
109pub struct FilteredAttrs<'a> {
110 attrs: &'a Attrs,
111 filter_key: &'a str,
112}
113
114impl<'a> FilteredAttrs<'a> {
115 pub fn new(
116 attrs: &'a Attrs,
117 filter_key: &'a str,
118 ) -> Self {
119 Self { attrs, filter_key }
120 }
121}
122
123impl<'a> Serialize for FilteredAttrs<'a> {
124 fn serialize<S>(
125 &self,
126 serializer: S,
127 ) -> Result<S::Ok, S::Error>
128 where
129 S: serde::Serializer,
130 {
131 let mut map = serde_json::Map::new();
132 if let Some(value) = self.attrs.get_safe(self.filter_key) {
133 map.insert(self.filter_key.to_string(), value.clone());
134 }
135 map.serialize(serializer)
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142 use serde_json::json;
143
144 #[test]
145 fn test_attrs_default() {
146 let attrs = Attrs::default();
147 assert!(attrs.attrs.is_empty());
148 }
149
150 #[test]
151 fn test_attrs_from() {
152 let mut map = HashMap::new();
153 map.insert("key1".to_string(), json!("value1"));
154 map.insert("key2".to_string(), json!(42));
155
156 let attrs = Attrs::from(map.clone());
157 assert_eq!(attrs.attrs, map);
158 }
159
160 #[test]
161 fn test_index_access() {
162 let mut attrs = Attrs::default();
163 attrs["key1"] = json!("value1");
164 attrs["key2"] = json!(42);
165 println!("attrs key1: {:?}", attrs["key1"]);
166 assert_eq!(attrs["key1"], json!("value1"));
167 assert_eq!(attrs["key2"], json!(42));
168 }
169
170 #[test]
171 fn test_index_mut_auto_create() {
172 let mut attrs = Attrs::default();
173 attrs["new_key"] = json!("new_value");
174 println!("attrs new_key: {:?}", attrs["new_key"]);
175 assert_eq!(attrs["new_key"], json!("new_value"));
176 }
177
178 #[test]
179 fn test_get_value() {
180 let mut attrs = Attrs::default();
181 attrs["string"] = json!("test");
182 attrs["number"] = json!(42);
183 attrs["boolean"] = json!(true);
184
185 assert_eq!(
186 attrs.get_value::<String>("string"),
187 Some("test".to_string())
188 );
189 assert_eq!(attrs.get_value::<i32>("number"), Some(42));
190 assert_eq!(attrs.get_value::<bool>("boolean"), Some(true));
191 assert_eq!(attrs.get_value::<String>("nonexistent"), None);
192 }
193
194 #[test]
195 fn test_update() {
196 let mut attrs = Attrs::default();
197 attrs["key1"] = json!("value1");
198
199 let mut new_values = HashMap::new();
200 new_values.insert("key2".to_string(), json!("value2"));
201 new_values.insert("key1".to_string(), json!("updated_value"));
202
203 let updated = attrs.update(new_values);
204
205 assert_eq!(updated["key1"], json!("updated_value"));
206 assert_eq!(updated["key2"], json!("value2"));
207 }
208
209 #[test]
210 fn test_deref() {
211 let mut attrs = Attrs::default();
212 attrs["key1"] = json!("value1");
213
214 assert_eq!(attrs.get("key1"), Some(&json!("value1")));
216
217 attrs.insert("key2".to_string(), json!("value2"));
219 assert_eq!(attrs["key2"], json!("value2"));
220 }
221
222 #[test]
223 #[should_panic(expected = "Key not found")]
224 fn test_index_panic() {
225 let attrs = Attrs::default();
226 let _ = attrs["nonexistent"];
227 }
228
229 #[test]
230 fn test_get_safe() {
231 let mut attrs = Attrs::default();
232 attrs["key1"] = json!("value1");
233
234 assert_eq!(attrs.get_safe("key1"), Some(&json!("value1")));
235 assert_eq!(attrs.get_safe("nonexistent"), None);
236 }
237}