1use std::{
2 cmp::{Eq, Ordering},
3 hash::{Hash, Hasher},
4 iter::FromIterator,
5 ops::{Index, IndexMut},
6};
7
8use serde_derive::{Deserialize, Serialize};
9
10use super::Value;
11
12#[derive(Clone, Debug, Default, Deserialize, Serialize)]
19#[serde(transparent)]
20pub struct Map(pub(crate) MapInner);
21
22#[cfg(not(feature = "indexmap"))]
23type MapInner = std::collections::BTreeMap<Value, Value>;
24#[cfg(feature = "indexmap")]
25type MapInner = indexmap::IndexMap<Value, Value>;
26
27impl Map {
28 #[must_use]
30 pub fn new() -> Self {
31 Self::default()
32 }
33
34 #[must_use]
36 pub fn len(&self) -> usize {
37 self.0.len()
38 }
39
40 #[must_use]
42 pub fn is_empty(&self) -> bool {
43 self.0.is_empty()
44 }
45
46 #[must_use]
48 pub fn get(&self, key: &Value) -> Option<&Value> {
49 self.0.get(key)
50 }
51
52 pub fn get_mut(&mut self, key: &Value) -> Option<&mut Value> {
54 self.0.get_mut(key)
55 }
56
57 pub fn insert(&mut self, key: impl Into<Value>, value: impl Into<Value>) -> Option<Value> {
60 self.0.insert(key.into(), value.into())
61 }
62
63 pub fn remove(&mut self, key: &Value) -> Option<Value> {
65 #[cfg(feature = "indexmap")]
66 {
67 self.0.shift_remove(key)
68 }
69 #[cfg(not(feature = "indexmap"))]
70 {
71 self.0.remove(key)
72 }
73 }
74
75 #[must_use]
77 pub fn iter(&self) -> impl DoubleEndedIterator<Item = (&Value, &Value)> {
78 self.0.iter()
79 }
80
81 #[must_use]
83 pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = (&Value, &mut Value)> {
84 self.0.iter_mut()
85 }
86
87 #[must_use]
89 pub fn keys(&self) -> impl DoubleEndedIterator<Item = &Value> {
90 self.0.keys()
91 }
92
93 #[must_use]
95 pub fn values(&self) -> impl DoubleEndedIterator<Item = &Value> {
96 self.0.values()
97 }
98
99 #[must_use]
101 pub fn values_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut Value> {
102 self.0.values_mut()
103 }
104
105 pub fn retain<F>(&mut self, keep: F)
112 where
113 F: FnMut(&Value, &mut Value) -> bool,
114 {
115 self.0.retain(keep);
116 }
117}
118
119impl Index<&Value> for Map {
120 type Output = Value;
121
122 #[allow(clippy::expect_used)]
123 fn index(&self, index: &Value) -> &Self::Output {
124 self.get(index).expect("no entry found for key")
125 }
126}
127
128impl IndexMut<&Value> for Map {
129 #[allow(clippy::expect_used)]
130 fn index_mut(&mut self, index: &Value) -> &mut Self::Output {
131 self.get_mut(index).expect("no entry found for key")
132 }
133}
134
135impl IntoIterator for Map {
136 type Item = (Value, Value);
137
138 type IntoIter = <MapInner as IntoIterator>::IntoIter;
139
140 fn into_iter(self) -> Self::IntoIter {
141 self.0.into_iter()
142 }
143}
144
145impl<K: Into<Value>, V: Into<Value>> FromIterator<(K, V)> for Map {
146 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
147 Map(iter
148 .into_iter()
149 .map(|(key, value)| (key.into(), value.into()))
150 .collect())
151 }
152}
153
154impl PartialEq for Map {
156 fn eq(&self, other: &Map) -> bool {
157 self.cmp(other).is_eq()
158 }
159}
160
161impl Eq for Map {}
163
164impl PartialOrd for Map {
165 fn partial_cmp(&self, other: &Map) -> Option<Ordering> {
166 Some(self.cmp(other))
167 }
168}
169
170impl Ord for Map {
171 fn cmp(&self, other: &Map) -> Ordering {
172 self.iter().cmp(other.iter())
173 }
174}
175
176impl Hash for Map {
177 fn hash<H: Hasher>(&self, state: &mut H) {
178 self.iter().for_each(|x| x.hash(state));
179 }
180}
181
182#[cfg(test)]
183mod tests {
184 use super::{Map, Value};
185
186 #[test]
187 fn map_usage() {
188 let mut map = Map::new();
189 assert_eq!(map.len(), 0);
190 assert!(map.is_empty());
191
192 map.insert("a", 42);
193 assert_eq!(map.len(), 1);
194 assert!(!map.is_empty());
195
196 assert_eq!(map.keys().collect::<Vec<_>>(), vec![&Value::from("a")]);
197 assert_eq!(map.values().collect::<Vec<_>>(), vec![&Value::from(42)]);
198 assert_eq!(
199 map.iter().collect::<Vec<_>>(),
200 vec![(&Value::from("a"), &Value::from(42))]
201 );
202
203 assert_eq!(map.get(&Value::from("a")), Some(&Value::from(42)));
204 assert_eq!(map.get(&Value::from("b")), None);
205 assert_eq!(map.get_mut(&Value::from("a")), Some(&mut Value::from(42)));
206 assert_eq!(map.get_mut(&Value::from("b")), None);
207
208 map[&Value::from("a")] = Value::from(24);
209 assert_eq!(&map[&Value::from("a")], &Value::from(24));
210
211 for (key, value) in map.iter_mut() {
212 if key == &Value::from("a") {
213 *value = Value::from(42);
214 }
215 }
216 assert_eq!(&map[&Value::from("a")], &Value::from(42));
217
218 map.values_mut().for_each(|value| *value = Value::from(24));
219 assert_eq!(&map[&Value::from("a")], &Value::from(24));
220
221 map.insert("b", 42);
222 assert_eq!(map.len(), 2);
223 assert!(!map.is_empty());
224 assert_eq!(map.get(&Value::from("a")), Some(&Value::from(24)));
225 assert_eq!(map.get(&Value::from("b")), Some(&Value::from(42)));
226
227 map.retain(|key, value| {
228 if key == &Value::from("a") {
229 *value = Value::from(42);
230 true
231 } else {
232 false
233 }
234 });
235 assert_eq!(map.len(), 1);
236 assert_eq!(map.get(&Value::from("a")), Some(&Value::from(42)));
237 assert_eq!(map.get(&Value::from("b")), None);
238
239 assert_eq!(map.remove(&Value::from("b")), None);
240 assert_eq!(map.remove(&Value::from("a")), Some(Value::from(42)));
241 assert_eq!(map.remove(&Value::from("a")), None);
242 }
243
244 #[test]
245 fn map_hash() {
246 assert_same_hash(&Map::new(), &Map::new());
247 assert_same_hash(
248 &[("a", 42)].into_iter().collect(),
249 &[("a", 42)].into_iter().collect(),
250 );
251 assert_same_hash(
252 &[("b", 24), ("c", 42)].into_iter().collect(),
253 &[("b", 24), ("c", 42)].into_iter().collect(),
254 );
255 }
256
257 fn assert_same_hash(a: &Map, b: &Map) {
258 use std::collections::hash_map::DefaultHasher;
259 use std::hash::{Hash, Hasher};
260
261 assert_eq!(a, b);
262 assert!(a.cmp(b).is_eq());
263 assert_eq!(a.partial_cmp(b), Some(std::cmp::Ordering::Equal));
264
265 let mut hasher = DefaultHasher::new();
266 a.hash(&mut hasher);
267 let h1 = hasher.finish();
268
269 let mut hasher = DefaultHasher::new();
270 b.hash(&mut hasher);
271 let h2 = hasher.finish();
272
273 assert_eq!(h1, h2);
274 }
275
276 #[test]
277 #[should_panic(expected = "no entry found for key")]
278 fn map_index_panic() {
279 let _ = &Map::new()[&Value::Unit];
280 }
281
282 #[test]
283 #[should_panic(expected = "no entry found for key")]
284 fn map_index_mut_panic() {
285 let _ = &mut Map::new()[&Value::Unit];
286 }
287}