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);