1
use std::{
2
    cmp::{Eq, Ordering},
3
    hash::{Hash, Hasher},
4
    iter::FromIterator,
5
    ops::{Index, IndexMut},
6
};
7

            
8
use serde_derive::{Deserialize, Serialize};
9

            
10
use 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)]
20
pub struct Map(pub(crate) MapInner);
21

            
22
#[cfg(not(feature = "indexmap"))]
23
type MapInner = std::collections::BTreeMap<Value, Value>;
24
#[cfg(feature = "indexmap")]
25
type MapInner = indexmap::IndexMap<Value, Value>;
26

            
27
impl Map {
28
    /// Creates a new, empty [`Map`].
29
    #[must_use]
30
74596
    pub fn new() -> Self {
31
74596
        Self::default()
32
74596
    }
33

            
34
    /// Returns the number of elements in the map.
35
    #[must_use]
36
854
    pub fn len(&self) -> usize {
37
854
        self.0.len()
38
854
    }
39

            
40
    /// Returns `true` if `self.len() == 0`, `false` otherwise.
41
    #[must_use]
42
12
    pub fn is_empty(&self) -> bool {
43
12
        self.0.is_empty()
44
12
    }
45

            
46
    /// Immutably looks up an element by its `key`.
47
    #[must_use]
48
316
    pub fn get(&self, key: &Value) -> Option<&Value> {
49
316
        self.0.get(key)
50
316
    }
51

            
52
    /// Mutably looks up an element by its `key`.
53
16
    pub fn get_mut(&mut self, key: &Value) -> Option<&mut Value> {
54
16
        self.0.get_mut(key)
55
16
    }
56

            
57
    /// Inserts a new element, returning the previous element with this `key` if
58
    /// there was any.
59
6392
    pub fn insert(&mut self, key: impl Into<Value>, value: impl Into<Value>) -> Option<Value> {
60
6392
        self.0.insert(key.into(), value.into())
61
6392
    }
62

            
63
    /// Removes an element by its `key`.
64
12
    pub fn remove(&mut self, key: &Value) -> Option<Value> {
65
12
        #[cfg(feature = "indexmap")]
66
12
        {
67
12
            self.0.shift_remove(key)
68
12
        }
69
12
        #[cfg(not(feature = "indexmap"))]
70
12
        {
71
12
            self.0.remove(key)
72
12
        }
73
12
    }
74

            
75
    /// Iterate all key-value pairs.
76
    #[must_use]
77
5096
    pub fn iter(&self) -> impl DoubleEndedIterator<Item = (&Value, &Value)> {
78
5096
        self.0.iter()
79
5096
    }
80

            
81
    /// Iterate all key-value pairs mutably.
82
    #[must_use]
83
4
    pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = (&Value, &mut Value)> {
84
4
        self.0.iter_mut()
85
4
    }
86

            
87
    /// Iterate all keys.
88
    #[must_use]
89
556
    pub fn keys(&self) -> impl DoubleEndedIterator<Item = &Value> {
90
556
        self.0.keys()
91
556
    }
92

            
93
    /// Iterate all values.
94
    #[must_use]
95
4
    pub fn values(&self) -> impl DoubleEndedIterator<Item = &Value> {
96
4
        self.0.values()
97
4
    }
98

            
99
    /// Iterate all values mutably.
100
    #[must_use]
101
4
    pub fn values_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut Value> {
102
4
        self.0.values_mut()
103
4
    }
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
4
    pub fn retain<F>(&mut self, keep: F)
112
4
    where
113
4
        F: FnMut(&Value, &mut Value) -> bool,
114
4
    {
115
4
        self.0.retain(keep);
116
4
    }
117
}
118

            
119
impl Index<&Value> for Map {
120
    type Output = Value;
121

            
122
    #[allow(clippy::expect_used)]
123
292
    fn index(&self, index: &Value) -> &Self::Output {
124
292
        self.get(index).expect("no entry found for key")
125
292
    }
126
}
127

            
128
impl IndexMut<&Value> for Map {
129
    #[allow(clippy::expect_used)]
130
8
    fn index_mut(&mut self, index: &Value) -> &mut Self::Output {
131
8
        self.get_mut(index).expect("no entry found for key")
132
8
    }
133
}
134

            
135
impl IntoIterator for Map {
136
    type Item = (Value, Value);
137

            
138
    type IntoIter = <MapInner as IntoIterator>::IntoIter;
139

            
140
838
    fn into_iter(self) -> Self::IntoIter {
141
838
        self.0.into_iter()
142
838
    }
143
}
144

            
145
impl<K: Into<Value>, V: Into<Value>> FromIterator<(K, V)> for Map {
146
76
    fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
147
76
        Map(iter
148
76
            .into_iter()
149
112
            .map(|(key, value)| (key.into(), value.into()))
150
76
            .collect())
151
76
    }
152
}
153

            
154
/// Note: equality is only given if both values and order of values match
155
impl PartialEq for Map {
156
2506
    fn eq(&self, other: &Map) -> bool {
157
2506
        self.cmp(other).is_eq()
158
2506
    }
159
}
160

            
161
/// Note: equality is only given if both values and order of values match
162
impl Eq for Map {}
163

            
164
impl PartialOrd for Map {
165
12
    fn partial_cmp(&self, other: &Map) -> Option<Ordering> {
166
12
        Some(self.cmp(other))
167
12
    }
168
}
169

            
170
impl Ord for Map {
171
2534
    fn cmp(&self, other: &Map) -> Ordering {
172
2534
        self.iter().cmp(other.iter())
173
2534
    }
174
}
175

            
176
impl Hash for Map {
177
24
    fn hash<H: Hasher>(&self, state: &mut H) {
178
24
        self.iter().for_each(|x| x.hash(state));
179
24
    }
180
}
181

            
182
#[cfg(test)]
183
mod tests {
184
    use super::{Map, Value};
185

            
186
    #[test]
187
4
    fn map_usage() {
188
4
        let mut map = Map::new();
189
4
        assert_eq!(map.len(), 0);
190
4
        assert!(map.is_empty());
191

            
192
4
        map.insert("a", 42);
193
4
        assert_eq!(map.len(), 1);
194
4
        assert!(!map.is_empty());
195

            
196
4
        assert_eq!(map.keys().collect::<Vec<_>>(), vec![&Value::from("a")]);
197
4
        assert_eq!(map.values().collect::<Vec<_>>(), vec![&Value::from(42)]);
198
4
        assert_eq!(
199
4
            map.iter().collect::<Vec<_>>(),
200
4
            vec![(&Value::from("a"), &Value::from(42))]
201
4
        );
202

            
203
4
        assert_eq!(map.get(&Value::from("a")), Some(&Value::from(42)));
204
4
        assert_eq!(map.get(&Value::from("b")), None);
205
4
        assert_eq!(map.get_mut(&Value::from("a")), Some(&mut Value::from(42)));
206
4
        assert_eq!(map.get_mut(&Value::from("b")), None);
207

            
208
4
        map[&Value::from("a")] = Value::from(24);
209
4
        assert_eq!(&map[&Value::from("a")], &Value::from(24));
210

            
211
4
        for (key, value) in map.iter_mut() {
212
4
            if key == &Value::from("a") {
213
4
                *value = Value::from(42);
214
4
            }
215
        }
216
4
        assert_eq!(&map[&Value::from("a")], &Value::from(42));
217

            
218
4
        map.values_mut().for_each(|value| *value = Value::from(24));
219
4
        assert_eq!(&map[&Value::from("a")], &Value::from(24));
220

            
221
4
        map.insert("b", 42);
222
4
        assert_eq!(map.len(), 2);
223
4
        assert!(!map.is_empty());
224
4
        assert_eq!(map.get(&Value::from("a")), Some(&Value::from(24)));
225
4
        assert_eq!(map.get(&Value::from("b")), Some(&Value::from(42)));
226

            
227
8
        map.retain(|key, value| {
228
8
            if key == &Value::from("a") {
229
4
                *value = Value::from(42);
230
4
                true
231
            } else {
232
4
                false
233
            }
234
8
        });
235
4
        assert_eq!(map.len(), 1);
236
4
        assert_eq!(map.get(&Value::from("a")), Some(&Value::from(42)));
237
4
        assert_eq!(map.get(&Value::from("b")), None);
238

            
239
4
        assert_eq!(map.remove(&Value::from("b")), None);
240
4
        assert_eq!(map.remove(&Value::from("a")), Some(Value::from(42)));
241
4
        assert_eq!(map.remove(&Value::from("a")), None);
242
4
    }
243

            
244
    #[test]
245
4
    fn map_hash() {
246
4
        assert_same_hash(&Map::new(), &Map::new());
247
4
        assert_same_hash(
248
4
            &[("a", 42)].into_iter().collect(),
249
4
            &[("a", 42)].into_iter().collect(),
250
4
        );
251
4
        assert_same_hash(
252
4
            &[("b", 24), ("c", 42)].into_iter().collect(),
253
4
            &[("b", 24), ("c", 42)].into_iter().collect(),
254
4
        );
255
4
    }
256

            
257
12
    fn assert_same_hash(a: &Map, b: &Map) {
258
        use std::collections::hash_map::DefaultHasher;
259
        use std::hash::{Hash, Hasher};
260

            
261
12
        assert_eq!(a, b);
262
12
        assert!(a.cmp(b).is_eq());
263
12
        assert_eq!(a.partial_cmp(b), Some(std::cmp::Ordering::Equal));
264

            
265
12
        let mut hasher = DefaultHasher::new();
266
12
        a.hash(&mut hasher);
267
12
        let h1 = hasher.finish();
268
12

            
269
12
        let mut hasher = DefaultHasher::new();
270
12
        b.hash(&mut hasher);
271
12
        let h2 = hasher.finish();
272
12

            
273
12
        assert_eq!(h1, h2);
274
12
    }
275

            
276
    #[test]
277
    #[should_panic(expected = "no entry found for key")]
278
4
    fn map_index_panic() {
279
4
        let _ = &Map::new()[&Value::Unit];
280
4
    }
281

            
282
    #[test]
283
    #[should_panic(expected = "no entry found for key")]
284
4
    fn map_index_mut_panic() {
285
4
        let _ = &mut Map::new()[&Value::Unit];
286
4
    }
287
}