ron/value/
map.rs

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/// A [`Value`] to [`Value`] map.
13///
14/// This structure either uses a [`BTreeMap`](std::collections::BTreeMap) or the
15/// [`IndexMap`](indexmap::IndexMap) internally.
16/// The latter can be used by enabling the `indexmap` feature. This can be used
17/// to preserve the order of the parsed map.
18#[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    /// Creates a new, empty [`Map`].
29    #[must_use]
30    pub fn new() -> Self {
31        Self::default()
32    }
33
34    /// Returns the number of elements in the map.
35    #[must_use]
36    pub fn len(&self) -> usize {
37        self.0.len()
38    }
39
40    /// Returns `true` if `self.len() == 0`, `false` otherwise.
41    #[must_use]
42    pub fn is_empty(&self) -> bool {
43        self.0.is_empty()
44    }
45
46    /// Immutably looks up an element by its `key`.
47    #[must_use]
48    pub fn get(&self, key: &Value) -> Option<&Value> {
49        self.0.get(key)
50    }
51
52    /// Mutably looks up an element by its `key`.
53    pub fn get_mut(&mut self, key: &Value) -> Option<&mut Value> {
54        self.0.get_mut(key)
55    }
56
57    /// Inserts a new element, returning the previous element with this `key` if
58    /// there was any.
59    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    /// Removes an element by its `key`.
64    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    /// Iterate all key-value pairs.
76    #[must_use]
77    pub fn iter(&self) -> impl DoubleEndedIterator<Item = (&Value, &Value)> {
78        self.0.iter()
79    }
80
81    /// Iterate all key-value pairs mutably.
82    #[must_use]
83    pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = (&Value, &mut Value)> {
84        self.0.iter_mut()
85    }
86
87    /// Iterate all keys.
88    #[must_use]
89    pub fn keys(&self) -> impl DoubleEndedIterator<Item = &Value> {
90        self.0.keys()
91    }
92
93    /// Iterate all values.
94    #[must_use]
95    pub fn values(&self) -> impl DoubleEndedIterator<Item = &Value> {
96        self.0.values()
97    }
98
99    /// Iterate all values mutably.
100    #[must_use]
101    pub fn values_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut Value> {
102        self.0.values_mut()
103    }
104
105    /// Retains only the elements specified by the `keep` predicate.
106    ///
107    /// In other words, remove all pairs `(k, v)` for which `keep(&k, &mut v)`
108    /// returns `false`.
109    ///
110    /// The elements are visited in iteration order.
111    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
154/// Note: equality is only given if both values and order of values match
155impl PartialEq for Map {
156    fn eq(&self, other: &Map) -> bool {
157        self.cmp(other).is_eq()
158    }
159}
160
161/// Note: equality is only given if both values and order of values match
162impl 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}