liquid_value/
map.rs

1//! A map implementation.
2//!
3//! This is to abstract the choice of map from the user so it can be changed without breaking
4//! compatibility.
5
6use std::borrow::{Borrow, Cow};
7use std::collections::hash_map;
8use std::fmt::{self, Debug};
9use std::hash::Hash;
10use std::iter::FromIterator;
11use std::ops;
12
13use serde::{de, ser};
14
15use super::Value;
16
17/// Type representing a Liquid object, payload of the `Value::Map` variant
18pub struct Map {
19    map: MapImpl<Key, Value>,
20}
21
22type Key = Cow<'static, str>;
23
24type MapImpl<K, V> = hash_map::HashMap<K, V>;
25type VacantEntryImpl<'a> = hash_map::VacantEntry<'a, Key, Value>;
26type OccupiedEntryImpl<'a> = hash_map::OccupiedEntry<'a, Key, Value>;
27type IterImpl<'a> = hash_map::Iter<'a, Key, Value>;
28type IterMutImpl<'a> = hash_map::IterMut<'a, Key, Value>;
29type IntoIterImpl = hash_map::IntoIter<Key, Value>;
30type KeysImpl<'a> = hash_map::Keys<'a, Key, Value>;
31type ValuesImpl<'a> = hash_map::Values<'a, Key, Value>;
32type ValuesMutImpl<'a> = hash_map::ValuesMut<'a, Key, Value>;
33
34impl Map {
35    /// Makes a new empty Map.
36    #[inline]
37    pub fn new() -> Self {
38        Map {
39            map: MapImpl::new(),
40        }
41    }
42
43    /// Clears the map, removing all values.
44    #[inline]
45    pub fn clear(&mut self) {
46        self.map.clear()
47    }
48
49    /// Returns a reference to the value corresponding to the key.
50    ///
51    /// The key may be any borrowed form of the map's key type, but the ordering
52    /// on the borrowed form *must* match the ordering on the key type.
53    #[inline]
54    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&Value>
55    where
56        Key: Borrow<Q>,
57        Q: Ord + Eq + Hash,
58    {
59        self.map.get(key)
60    }
61
62    /// Returns true if the map contains a value for the specified key.
63    ///
64    /// The key may be any borrowed form of the map's key type, but the ordering
65    /// on the borrowed form *must* match the ordering on the key type.
66    #[inline]
67    pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
68    where
69        Key: Borrow<Q>,
70        Q: Ord + Eq + Hash,
71    {
72        self.map.contains_key(key)
73    }
74
75    /// Returns a mutable reference to the value corresponding to the key.
76    ///
77    /// The key may be any borrowed form of the map's key type, but the ordering
78    /// on the borrowed form *must* match the ordering on the key type.
79    #[inline]
80    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut Value>
81    where
82        Key: Borrow<Q>,
83        Q: Ord + Eq + Hash,
84    {
85        self.map.get_mut(key)
86    }
87
88    /// Inserts a key-value pair into the map.
89    ///
90    /// If the map did not have this key present, `None` is returned.
91    ///
92    /// If the map did have this key present, the value is updated, and the old
93    /// value is returned.
94    #[inline]
95    pub fn insert(&mut self, k: Key, v: Value) -> Option<Value> {
96        self.map.insert(k, v)
97    }
98
99    /// Removes a key from the map, returning the value at the key if the key
100    /// was previously in the map.
101    ///
102    /// The key may be any borrowed form of the map's key type, but the ordering
103    /// on the borrowed form *must* match the ordering on the key type.
104    #[inline]
105    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<Value>
106    where
107        Key: Borrow<Q>,
108        Q: Ord + Eq + Hash,
109    {
110        self.map.remove(key)
111    }
112
113    /// Gets the given key's corresponding entry in the map for in-place
114    /// manipulation.
115    pub fn entry<S>(&mut self, key: S) -> Entry<'_>
116    where
117        S: Into<Key>,
118    {
119        use std::collections::hash_map::Entry as EntryImpl;
120        match self.map.entry(key.into()) {
121            EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
122            EntryImpl::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
123        }
124    }
125
126    /// Returns the number of elements in the map.
127    #[inline]
128    pub fn len(&self) -> usize {
129        self.map.len()
130    }
131
132    /// Returns true if the map contains no elements.
133    #[inline]
134    pub fn is_empty(&self) -> bool {
135        self.map.is_empty()
136    }
137
138    /// Gets an iterator over the entries of the map.
139    #[inline]
140    pub fn iter(&self) -> Iter<'_> {
141        Iter {
142            iter: self.map.iter(),
143        }
144    }
145
146    /// Gets a mutable iterator over the entries of the map.
147    #[inline]
148    pub fn iter_mut(&mut self) -> IterMut<'_> {
149        IterMut {
150            iter: self.map.iter_mut(),
151        }
152    }
153
154    /// Gets an iterator over the keys of the map.
155    #[inline]
156    pub fn keys(&self) -> Keys<'_> {
157        Keys {
158            iter: self.map.keys(),
159        }
160    }
161
162    /// Gets an iterator over the values of the map.
163    #[inline]
164    pub fn values(&self) -> Values<'_> {
165        Values {
166            iter: self.map.values(),
167        }
168    }
169
170    /// Gets an iterator over mutable values of the map.
171    #[inline]
172    pub fn values_mut(&mut self) -> ValuesMut<'_> {
173        ValuesMut {
174            iter: self.map.values_mut(),
175        }
176    }
177}
178
179impl Default for Map {
180    #[inline]
181    fn default() -> Self {
182        Map {
183            map: MapImpl::new(),
184        }
185    }
186}
187
188impl Clone for Map {
189    #[inline]
190    fn clone(&self) -> Self {
191        Map {
192            map: self.map.clone(),
193        }
194    }
195}
196
197impl PartialEq for Map {
198    #[inline]
199    fn eq(&self, other: &Self) -> bool {
200        self.map.eq(&other.map)
201    }
202}
203
204impl Eq for Map {}
205
206/// Access an element of this map. Panics if the given key is not present in the
207/// map.
208///
209/// ```rust
210/// # use liquid_value::Value;
211/// #
212/// # let val = &Value::scalar("");
213/// # let _ =
214/// match *val {
215///     Value::Scalar(ref s) => Some(s.to_str()),
216///     Value::Array(ref arr) => Some(arr[0].to_str()),
217///     Value::Object(ref map) => Some(map["type"].to_str()),
218///     _ => None,
219/// }
220/// # ;
221/// ```
222impl<'a, Q: ?Sized> ops::Index<&'a Q> for Map
223where
224    Key: Borrow<Q>,
225    Q: Ord + Eq + Hash,
226{
227    type Output = Value;
228
229    fn index(&self, index: &Q) -> &Value {
230        self.map.index(index)
231    }
232}
233
234/// Mutably access an element of this map. Panics if the given key is not
235/// present in the map.
236///
237/// ```rust
238/// # #[macro_use]
239/// # extern crate liquid_value;
240/// #
241/// # fn main() {
242/// #     let mut map = liquid_value::map::Map::new();
243/// #     map.insert("key".into(), liquid_value::Value::Nil);
244/// #
245/// map["key"] = liquid_value!("value");
246/// # }
247/// ```
248impl<'a, Q: ?Sized> ops::IndexMut<&'a Q> for Map
249where
250    Key: Borrow<Q>,
251    Q: Ord + Eq + Hash,
252{
253    fn index_mut(&mut self, index: &Q) -> &mut Value {
254        self.map.get_mut(index).expect("no entry found for key")
255    }
256}
257
258impl Debug for Map {
259    #[inline]
260    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
261        self.map.fmt(formatter)
262    }
263}
264
265impl ser::Serialize for Map {
266    #[inline]
267    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
268    where
269        S: ser::Serializer,
270    {
271        use serde::ser::SerializeMap;
272        let mut map = serializer.serialize_map(Some(self.len()))?;
273        for (k, v) in self {
274            map.serialize_key(k)?;
275            map.serialize_value(v)?;
276        }
277        map.end()
278    }
279}
280
281impl<'de> de::Deserialize<'de> for Map {
282    #[inline]
283    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
284    where
285        D: de::Deserializer<'de>,
286    {
287        struct Visitor;
288
289        impl<'de> de::Visitor<'de> for Visitor {
290            type Value = Map;
291
292            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
293                formatter.write_str("a map")
294            }
295
296            #[inline]
297            fn visit_unit<E>(self) -> Result<Self::Value, E>
298            where
299                E: de::Error,
300            {
301                Ok(Map::new())
302            }
303
304            #[inline]
305            fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
306            where
307                V: de::MapAccess<'de>,
308            {
309                let mut values = Map::new();
310
311                while let Some((key, value)) = visitor.next_entry()? {
312                    values.insert(key, value);
313                }
314
315                Ok(values)
316            }
317        }
318
319        deserializer.deserialize_map(Visitor)
320    }
321}
322
323impl FromIterator<(Key, Value)> for Map {
324    fn from_iter<T>(iter: T) -> Self
325    where
326        T: IntoIterator<Item = (Key, Value)>,
327    {
328        Map {
329            map: FromIterator::from_iter(iter),
330        }
331    }
332}
333
334impl Extend<(Key, Value)> for Map {
335    fn extend<T>(&mut self, iter: T)
336    where
337        T: IntoIterator<Item = (Key, Value)>,
338    {
339        self.map.extend(iter);
340    }
341}
342
343macro_rules! delegate_iterator {
344    (($name:ident $($generics:tt)*) => $item:ty) => {
345        impl $($generics)* Iterator for $name $($generics)* {
346            type Item = $item;
347            #[inline]
348            fn next(&mut self) -> Option<Self::Item> {
349                self.iter.next()
350            }
351            #[inline]
352            fn size_hint(&self) -> (usize, Option<usize>) {
353                self.iter.size_hint()
354            }
355        }
356
357        impl $($generics)* ExactSizeIterator for $name $($generics)* {
358            #[inline]
359            fn len(&self) -> usize {
360                self.iter.len()
361            }
362        }
363    }
364}
365
366//////////////////////////////////////////////////////////////////////////////
367
368/// A view into a single entry in a map, which may either be vacant or occupied.
369/// This enum is constructed from the [`entry`] method on [`Map`].
370///
371/// [`entry`]: struct.Map.html#method.entry
372/// [`Map`]: struct.Map.html
373#[derive(Debug)]
374pub enum Entry<'a> {
375    /// A vacant Entry.
376    Vacant(VacantEntry<'a>),
377    /// An occupied Entry.
378    Occupied(OccupiedEntry<'a>),
379}
380
381/// A vacant Entry. It is part of the [`Entry`] enum.
382///
383/// [`Entry`]: enum.Entry.html
384#[derive(Debug)]
385pub struct VacantEntry<'a> {
386    vacant: VacantEntryImpl<'a>,
387}
388
389/// An occupied Entry. It is part of the [`Entry`] enum.
390///
391/// [`Entry`]: enum.Entry.html
392#[derive(Debug)]
393pub struct OccupiedEntry<'a> {
394    occupied: OccupiedEntryImpl<'a>,
395}
396
397impl<'a> Entry<'a> {
398    /// Returns a reference to this entry's key.
399    ///
400    /// # Examples
401    ///
402    /// ```rust
403    /// let mut map = liquid_value::map::Map::new();
404    /// assert_eq!(map.entry("liquid").key(), &"liquid");
405    /// ```
406    pub fn key(&self) -> &Key {
407        match *self {
408            Entry::Vacant(ref e) => e.key(),
409            Entry::Occupied(ref e) => e.key(),
410        }
411    }
412
413    /// Ensures a value is in the entry by inserting the default if empty, and
414    /// returns a mutable reference to the value in the entry.
415    ///
416    /// # Examples
417    ///
418    /// ```rust
419    /// # #[macro_use]
420    /// # extern crate liquid_value;
421    /// #
422    /// # fn main() {
423    /// let mut map = liquid_value::map::Map::new();
424    /// map.entry("liquid").or_insert(liquid_value!(12));
425    ///
426    /// assert_eq!(map["liquid"], liquid_value!(12));
427    /// # }
428    /// ```
429    pub fn or_insert(self, default: Value) -> &'a mut Value {
430        match self {
431            Entry::Vacant(entry) => entry.insert(default),
432            Entry::Occupied(entry) => entry.into_mut(),
433        }
434    }
435
436    /// Ensures a value is in the entry by inserting the result of the default
437    /// function if empty, and returns a mutable reference to the value in the
438    /// entry.
439    ///
440    /// # Examples
441    ///
442    /// ```rust
443    /// # #[macro_use]
444    /// # extern crate liquid_value;
445    /// #
446    /// # fn main() {
447    /// let mut map = liquid_value::map::Map::new();
448    /// map.entry("liquid").or_insert_with(|| liquid_value!("hoho"));
449    ///
450    /// assert_eq!(map["liquid"], liquid_value!("hoho"));
451    /// # }
452    /// ```
453    pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
454    where
455        F: FnOnce() -> Value,
456    {
457        match self {
458            Entry::Vacant(entry) => entry.insert(default()),
459            Entry::Occupied(entry) => entry.into_mut(),
460        }
461    }
462}
463
464impl<'a> VacantEntry<'a> {
465    /// Gets a reference to the key that would be used when inserting a value
466    /// through the VacantEntry.
467    ///
468    /// # Examples
469    ///
470    /// ```rust
471    /// use liquid_value::map::Entry;
472    ///
473    /// let mut map = liquid_value::map::Map::new();
474    ///
475    /// match map.entry("liquid") {
476    ///     Entry::Vacant(vacant) => {
477    ///         assert_eq!(vacant.key(), &"liquid");
478    ///     }
479    ///     Entry::Occupied(_) => unimplemented!(),
480    /// }
481    /// ```
482    #[inline]
483    pub fn key(&self) -> &Key {
484        self.vacant.key()
485    }
486
487    /// Sets the value of the entry with the VacantEntry's key, and returns a
488    /// mutable reference to it.
489    ///
490    /// # Examples
491    ///
492    /// ```rust
493    /// # #[macro_use]
494    /// # extern crate liquid_value;
495    /// #
496    /// # fn main() {
497    /// use liquid_value::map::Entry;
498    ///
499    /// let mut map = liquid_value::map::Map::new();
500    ///
501    /// match map.entry("liquid") {
502    ///     Entry::Vacant(vacant) => {
503    ///         vacant.insert(liquid_value!("hoho"));
504    ///     }
505    ///     Entry::Occupied(_) => unimplemented!(),
506    /// }
507    /// # }
508    /// ```
509    #[inline]
510    pub fn insert(self, value: Value) -> &'a mut Value {
511        self.vacant.insert(value)
512    }
513}
514
515impl<'a> OccupiedEntry<'a> {
516    /// Gets a reference to the key in the entry.
517    ///
518    /// # Examples
519    ///
520    /// ```rust
521    /// # #[macro_use]
522    /// # extern crate liquid_value;
523    /// #
524    /// # fn main() {
525    /// use liquid_value::map::Entry;
526    ///
527    /// let mut map = liquid_value::map::Map::new();
528    /// map.insert("liquid".into(), liquid_value!(12));
529    ///
530    /// match map.entry("liquid") {
531    ///     Entry::Occupied(occupied) => {
532    ///         assert_eq!(occupied.key(), &"liquid");
533    ///     }
534    ///     Entry::Vacant(_) => unimplemented!(),
535    /// }
536    /// # }
537    /// ```
538    #[inline]
539    pub fn key(&self) -> &Key {
540        self.occupied.key()
541    }
542
543    /// Gets a reference to the value in the entry.
544    ///
545    /// # Examples
546    ///
547    /// ```rust
548    /// # #[macro_use]
549    /// # extern crate liquid_value;
550    /// #
551    /// # fn main() {
552    /// use liquid_value::map::Entry;
553    ///
554    /// let mut map = liquid_value::map::Map::new();
555    /// map.insert("liquid".into(), liquid_value!(12));
556    ///
557    /// match map.entry("liquid") {
558    ///     Entry::Occupied(occupied) => {
559    ///         assert_eq!(occupied.get(), &liquid_value!(12));
560    ///     }
561    ///     Entry::Vacant(_) => unimplemented!(),
562    /// }
563    /// # }
564    /// ```
565    #[inline]
566    pub fn get(&self) -> &Value {
567        self.occupied.get()
568    }
569
570    /// Gets a mutable reference to the value in the entry.
571    ///
572    /// # Examples
573    ///
574    /// ```rust
575    /// # #[macro_use]
576    /// # extern crate liquid_value;
577    /// #
578    /// # fn main() {
579    /// use liquid_value::map::Entry;
580    ///
581    /// let mut map = liquid_value::map::Map::new();
582    /// map.insert("liquid".into(), liquid_value!([1, 2, 3]));
583    ///
584    /// match map.entry("liquid") {
585    ///     Entry::Occupied(mut occupied) => {
586    ///         occupied.get_mut().as_array_mut().unwrap().push(liquid_value!(4));
587    ///     }
588    ///     Entry::Vacant(_) => unimplemented!(),
589    /// }
590    ///
591    /// assert_eq!(map["liquid"].as_array().unwrap().len(), 4);
592    /// # }
593    /// ```
594    #[inline]
595    pub fn get_mut(&mut self) -> &mut Value {
596        self.occupied.get_mut()
597    }
598
599    /// Converts the entry into a mutable reference to its value.
600    ///
601    /// # Examples
602    ///
603    /// ```rust
604    /// # #[macro_use]
605    /// # extern crate liquid_value;
606    /// #
607    /// # fn main() {
608    /// use liquid_value::map::Entry;
609    ///
610    /// let mut map = liquid_value::map::Map::new();
611    /// map.insert("liquid".into(), liquid_value!([1, 2, 3]));
612    ///
613    /// match map.entry("liquid") {
614    ///     Entry::Occupied(mut occupied) => {
615    ///         occupied.into_mut().as_array_mut().unwrap().push(liquid_value!(4));
616    ///     }
617    ///     Entry::Vacant(_) => unimplemented!(),
618    /// }
619    ///
620    /// assert_eq!(map["liquid"].as_array().unwrap().len(), 4);
621    /// # }
622    /// ```
623    #[inline]
624    pub fn into_mut(self) -> &'a mut Value {
625        self.occupied.into_mut()
626    }
627
628    /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns
629    /// the entry's old value.
630    ///
631    /// # Examples
632    ///
633    /// ```rust
634    /// # #[macro_use]
635    /// # extern crate liquid_value;
636    /// #
637    /// # fn main() {
638    /// use liquid_value::map::Entry;
639    ///
640    /// let mut map = liquid_value::map::Map::new();
641    /// map.insert("liquid".into(), liquid_value!(12));
642    ///
643    /// match map.entry("liquid") {
644    ///     Entry::Occupied(mut occupied) => {
645    ///         assert_eq!(occupied.insert(liquid_value!(13)), liquid_value!(12));
646    ///         assert_eq!(occupied.get(), &liquid_value!(13));
647    ///     }
648    ///     Entry::Vacant(_) => unimplemented!(),
649    /// }
650    /// # }
651    /// ```
652    #[inline]
653    pub fn insert(&mut self, value: Value) -> Value {
654        self.occupied.insert(value)
655    }
656
657    /// Takes the value of the entry out of the map, and returns it.
658    ///
659    /// # Examples
660    ///
661    /// ```rust
662    /// # #[macro_use]
663    /// # extern crate liquid_value;
664    /// #
665    /// # fn main() {
666    /// use liquid_value::map::Entry;
667    ///
668    /// let mut map = liquid_value::map::Map::new();
669    /// map.insert("liquid".into(), liquid_value!(12));
670    ///
671    /// match map.entry("liquid") {
672    ///     Entry::Occupied(occupied) => {
673    ///         assert_eq!(occupied.remove(), liquid_value!(12));
674    ///     }
675    ///     Entry::Vacant(_) => unimplemented!(),
676    /// }
677    /// # }
678    /// ```
679    #[inline]
680    pub fn remove(self) -> Value {
681        self.occupied.remove()
682    }
683}
684
685//////////////////////////////////////////////////////////////////////////////
686
687impl<'a> IntoIterator for &'a Map {
688    type Item = (&'a Key, &'a Value);
689    type IntoIter = Iter<'a>;
690    #[inline]
691    fn into_iter(self) -> Self::IntoIter {
692        Iter {
693            iter: self.map.iter(),
694        }
695    }
696}
697
698/// An iterator over a liquid_value::map::Map's entries.
699#[derive(Debug)]
700pub struct Iter<'a> {
701    iter: IterImpl<'a>,
702}
703
704delegate_iterator!((Iter<'a>) => (&'a Key, &'a Value));
705
706//////////////////////////////////////////////////////////////////////////////
707
708impl<'a> IntoIterator for &'a mut Map {
709    type Item = (&'a Key, &'a mut Value);
710    type IntoIter = IterMut<'a>;
711    #[inline]
712    fn into_iter(self) -> Self::IntoIter {
713        IterMut {
714            iter: self.map.iter_mut(),
715        }
716    }
717}
718
719/// A mutable iterator over a liquid_value::map::Map's entries.
720#[derive(Debug)]
721pub struct IterMut<'a> {
722    iter: IterMutImpl<'a>,
723}
724
725delegate_iterator!((IterMut<'a>) => (&'a Key, &'a mut Value));
726
727//////////////////////////////////////////////////////////////////////////////
728
729impl IntoIterator for Map {
730    type Item = (Key, Value);
731    type IntoIter = IntoIter;
732    #[inline]
733    fn into_iter(self) -> Self::IntoIter {
734        IntoIter {
735            iter: self.map.into_iter(),
736        }
737    }
738}
739
740/// An owning iterator over a liquid_value::map::Map's entries.
741#[derive(Debug)]
742pub struct IntoIter {
743    iter: IntoIterImpl,
744}
745
746delegate_iterator!((IntoIter) => (Key, Value));
747
748//////////////////////////////////////////////////////////////////////////////
749
750/// An iterator over a liquid_value::map::Map's keys.
751#[derive(Debug)]
752pub struct Keys<'a> {
753    iter: KeysImpl<'a>,
754}
755
756delegate_iterator!((Keys<'a>) => &'a Key);
757
758//////////////////////////////////////////////////////////////////////////////
759
760/// An iterator over a liquid_value::map::Map's values.
761#[derive(Debug)]
762pub struct Values<'a> {
763    iter: ValuesImpl<'a>,
764}
765
766delegate_iterator!((Values<'a>) => &'a Value);
767
768//////////////////////////////////////////////////////////////////////////////
769
770/// A mutable iterator over a liquid_value::map::Map's values.
771#[derive(Debug)]
772pub struct ValuesMut<'a> {
773    iter: ValuesMutImpl<'a>,
774}
775
776delegate_iterator!((ValuesMut<'a>) => &'a mut Value);