1use core::{
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 = alloc::collections::BTreeMap<Value, Value>;
24#[cfg(feature = "indexmap")]
25type MapInner = indexmap::IndexMap<Value, Value, std::collections::hash_map::RandomState>;
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 alloc::{vec, vec::Vec};
185
186 use super::{Map, Value};
187
188 #[test]
189 fn map_usage() {
190 let mut map = Map::new();
191 assert_eq!(map.len(), 0);
192 assert!(map.is_empty());
193
194 map.insert("a", 42);
195 assert_eq!(map.len(), 1);
196 assert!(!map.is_empty());
197
198 assert_eq!(map.keys().collect::<Vec<_>>(), vec![&Value::from("a")]);
199 assert_eq!(map.values().collect::<Vec<_>>(), vec![&Value::from(42)]);
200 assert_eq!(
201 map.iter().collect::<Vec<_>>(),
202 vec![(&Value::from("a"), &Value::from(42))]
203 );
204
205 assert_eq!(map.get(&Value::from("a")), Some(&Value::from(42)));
206 assert_eq!(map.get(&Value::from("b")), None);
207 assert_eq!(map.get_mut(&Value::from("a")), Some(&mut Value::from(42)));
208 assert_eq!(map.get_mut(&Value::from("b")), None);
209
210 map[&Value::from("a")] = Value::from(24);
211 assert_eq!(&map[&Value::from("a")], &Value::from(24));
212
213 for (key, value) in map.iter_mut() {
214 if key == &Value::from("a") {
215 *value = Value::from(42);
216 }
217 }
218 assert_eq!(&map[&Value::from("a")], &Value::from(42));
219
220 map.values_mut().for_each(|value| *value = Value::from(24));
221 assert_eq!(&map[&Value::from("a")], &Value::from(24));
222
223 map.insert("b", 42);
224 assert_eq!(map.len(), 2);
225 assert!(!map.is_empty());
226 assert_eq!(map.get(&Value::from("a")), Some(&Value::from(24)));
227 assert_eq!(map.get(&Value::from("b")), Some(&Value::from(42)));
228
229 map.retain(|key, value| {
230 if key == &Value::from("a") {
231 *value = Value::from(42);
232 true
233 } else {
234 false
235 }
236 });
237 assert_eq!(map.len(), 1);
238 assert_eq!(map.get(&Value::from("a")), Some(&Value::from(42)));
239 assert_eq!(map.get(&Value::from("b")), None);
240
241 assert_eq!(map.remove(&Value::from("b")), None);
242 assert_eq!(map.remove(&Value::from("a")), Some(Value::from(42)));
243 assert_eq!(map.remove(&Value::from("a")), None);
244 }
245
246 #[cfg(feature = "std")]
247 #[test]
248 fn map_hash() {
249 assert_same_hash(&Map::new(), &Map::new());
250 assert_same_hash(
251 &[("a", 42)].into_iter().collect(),
252 &[("a", 42)].into_iter().collect(),
253 );
254 assert_same_hash(
255 &[("b", 24), ("c", 42)].into_iter().collect(),
256 &[("b", 24), ("c", 42)].into_iter().collect(),
257 );
258 }
259
260 #[cfg(feature = "std")]
261 fn assert_same_hash(a: &Map, b: &Map) {
262 use core::hash::{Hash, Hasher};
263 use std::collections::hash_map::DefaultHasher;
264
265 assert_eq!(a, b);
266 assert!(a.cmp(b).is_eq());
267 assert_eq!(a.partial_cmp(b), Some(core::cmp::Ordering::Equal));
268
269 let mut hasher = DefaultHasher::new();
270 a.hash(&mut hasher);
271 let h1 = hasher.finish();
272
273 let mut hasher = DefaultHasher::new();
274 b.hash(&mut hasher);
275 let h2 = hasher.finish();
276
277 assert_eq!(h1, h2);
278 }
279
280 #[test]
281 #[should_panic(expected = "no entry found for key")]
282 fn map_index_panic() {
283 let _ = &Map::new()[&Value::Unit];
284 }
285
286 #[test]
287 #[should_panic(expected = "no entry found for key")]
288 fn map_index_mut_panic() {
289 let _ = &mut Map::new()[&Value::Unit];
290 }
291}