1use serde::de::{SeqAccess, Visitor};
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use std::collections::HashMap;
4use std::fmt;
5use std::hash::Hash;
6
7#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct Map<TKey, TValue>
13where
14 TKey: Eq + Hash + Clone + PartialEq,
15 TValue: Clone + PartialEq,
16{
17 pub entries: Vec<(TKey, TValue)>,
19}
20
21impl<TKey, TValue> Default for Map<TKey, TValue>
22where
23 TKey: Eq + Hash + Clone + PartialEq,
24 TValue: Clone + PartialEq,
25{
26 fn default() -> Self {
27 Map {
28 entries: Vec::new(),
29 }
30 }
31}
32
33impl<TKey, TValue> Map<TKey, TValue>
34where
35 TKey: Eq + Hash + Clone + PartialEq,
36 TValue: Clone + PartialEq,
37{
38 pub fn new() -> Self {
40 Self::default()
41 }
42
43 pub fn from(entries: Vec<(TKey, TValue)>) -> Self {
45 Map { entries }
46 }
47
48 pub fn add(&mut self, key: TKey, value: TValue) {
50 self.entries.push((key, value));
51 }
52
53 pub fn len(&self) -> usize {
55 self.entries.len()
56 }
57
58 pub fn is_empty(&self) -> bool {
60 self.entries.is_empty()
61 }
62
63 pub fn contains_key(&self, key: &TKey) -> bool {
65 self.entries.iter().any(|(k, _)| k == key)
66 }
67
68 pub fn get(&self, key: &TKey) -> Option<&TValue> {
70 self.entries.iter().find(|(k, _)| k == key).map(|(_, v)| v)
71 }
72}
73
74impl<TKey, TValue> Serialize for Map<TKey, TValue>
76where
77 TKey: Eq + Hash + Clone + Serialize + PartialEq,
78 TValue: Clone + Serialize + PartialEq,
79{
80 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
81 use serde::ser::SerializeSeq;
82
83 let mut seq = serializer.serialize_seq(Some(self.entries.len()))?;
84 for (key, value) in &self.entries {
85 let mut hm = HashMap::new();
86 hm.insert(key, value);
87 seq.serialize_element(&hm)?;
88 }
89 seq.end()
90 }
91}
92
93impl<'de, TKey, TValue> Deserialize<'de> for Map<TKey, TValue>
95where
96 TKey: Eq + Hash + Clone + Deserialize<'de> + PartialEq,
97 TValue: Clone + Deserialize<'de> + PartialEq,
98{
99 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
100 struct MapVisitor<TKey, TValue> {
101 _phantom: std::marker::PhantomData<(TKey, TValue)>,
102 }
103
104 impl<'de, TKey, TValue> Visitor<'de> for MapVisitor<TKey, TValue>
105 where
106 TKey: Eq + Hash + Clone + Deserialize<'de> + PartialEq,
107 TValue: Clone + Deserialize<'de> + PartialEq,
108 {
109 type Value = Map<TKey, TValue>;
110
111 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
112 formatter.write_str("an array of single-key objects")
113 }
114
115 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
116 let mut entries = Vec::new();
117 while let Some(hm) = seq.next_element::<HashMap<TKey, TValue>>()? {
118 for (k, v) in hm {
119 entries.push((k, v));
120 }
121 }
122 Ok(Map { entries })
123 }
124 }
125
126 deserializer.deserialize_seq(MapVisitor {
127 _phantom: std::marker::PhantomData,
128 })
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn test_map_new() {
138 let map: Map<String, String> = Map::new();
139 assert!(map.is_empty());
140 assert_eq!(map.len(), 0);
141 }
142
143 #[test]
144 fn test_map_default() {
145 let map: Map<String, String> = Map::default();
146 assert!(map.is_empty());
147 }
148
149 #[test]
150 fn test_map_from_entries() {
151 let map: Map<String, String> = Map::from(vec![
152 ("key1".to_string(), "value1".to_string()),
153 ("key2".to_string(), "value2".to_string()),
154 ]);
155 assert_eq!(map.len(), 2);
156 assert_eq!(map.get(&"key1".to_string()), Some(&"value1".to_string()));
157 assert_eq!(map.get(&"key2".to_string()), Some(&"value2".to_string()));
158 }
159
160 #[test]
161 fn test_map_add() {
162 let mut map: Map<String, String> = Map::new();
163 map.add("key1".to_string(), "value1".to_string());
164 map.add("key2".to_string(), "value2".to_string());
165 assert_eq!(map.len(), 2);
166 assert_eq!(map.get(&"key1".to_string()), Some(&"value1".to_string()));
167 }
168
169 #[test]
170 fn test_map_contains_key() {
171 let map: Map<String, String> = Map::from(vec![("key1".to_string(), "value1".to_string())]);
172 assert!(map.contains_key(&"key1".to_string()));
173 assert!(!map.contains_key(&"key2".to_string()));
174 }
175
176 #[test]
177 fn test_map_get_missing_key() {
178 let map: Map<String, String> = Map::from(vec![("key1".to_string(), "value1".to_string())]);
179 assert!(map.get(&"nonexistent".to_string()).is_none());
180 }
181
182 #[test]
183 fn test_map_serde_roundtrip() {
184 let map: Map<String, String> = Map::from(vec![
185 ("task1".to_string(), "value1".to_string()),
186 ("task2".to_string(), "value2".to_string()),
187 ]);
188 let json = serde_json::to_string(&map).unwrap();
189 let deserialized: Map<String, String> = serde_json::from_str(&json).unwrap();
190 assert_eq!(map, deserialized);
191 }
192
193 #[test]
194 fn test_map_serializes_to_array_of_single_key_objects() {
195 let map: Map<String, i32> = Map::from(vec![("a".to_string(), 1), ("b".to_string(), 2)]);
196 let json = serde_json::to_string(&map).unwrap();
197 assert_eq!(json, r#"[{"a":1},{"b":2}]"#);
198 }
199
200 #[test]
201 fn test_map_deserializes_from_array_of_single_key_objects() {
202 let json = r#"[{"a":1},{"b":2}]"#;
203 let map: Map<String, i32> = serde_json::from_str(json).unwrap();
204 assert_eq!(map.len(), 2);
205 assert_eq!(map.get(&"a".to_string()), Some(&1));
206 assert_eq!(map.get(&"b".to_string()), Some(&2));
207 }
208}