Skip to main content

serde_yaml/
mapping.rs

1//! A YAML mapping and its iterator types.
2
3use std::{
4    cmp::Ordering,
5    collections::hash_map::DefaultHasher,
6    fmt::{self, Display},
7    hash::{Hash, Hasher},
8    mem,
9};
10
11use indexmap::IndexMap;
12use serde::{Deserialize, Deserializer, Serialize};
13
14use crate::{Value, private};
15
16/// A YAML mapping in which the keys and values are both `serde_yaml::Value`.
17#[derive(Clone, Default, Eq, PartialEq)]
18pub struct Mapping {
19    map: IndexMap<Value, Value>,
20}
21
22impl Mapping {
23    /// Creates an empty YAML map.
24    #[inline]
25    pub fn new() -> Self {
26        Self::default()
27    }
28
29    /// Creates an empty YAML map with the given initial capacity.
30    #[inline]
31    pub fn with_capacity(capacity: usize) -> Self {
32        Mapping {
33            map: IndexMap::with_capacity(capacity),
34        }
35    }
36
37    /// Reserves capacity for at least `additional` more elements to be inserted
38    /// into the map. The map may reserve more space to avoid frequent
39    /// allocations.
40    ///
41    /// # Panics
42    ///
43    /// Panics if the new allocation size overflows `usize`.
44    #[inline]
45    pub fn reserve(&mut self, additional: usize) {
46        self.map.reserve(additional);
47    }
48
49    /// Shrinks the capacity of the map as much as possible. It will drop down
50    /// as much as possible while maintaining the internal rules and possibly
51    /// leaving some space in accordance with the resize policy.
52    #[inline]
53    pub fn shrink_to_fit(&mut self) {
54        self.map.shrink_to_fit();
55    }
56
57    /// Inserts a key-value pair into the map. If the key already existed, the
58    /// old value is returned.
59    #[inline]
60    pub fn insert(&mut self, k: Value, v: Value) -> Option<Value> {
61        self.map.insert(k, v)
62    }
63
64    /// Checks if the map contains the given key.
65    #[inline]
66    pub fn contains_key<I: Index>(&self, index: I) -> bool {
67        index.is_key_into(self)
68    }
69
70    /// Returns the value corresponding to the key in the map.
71    #[inline]
72    pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
73        index.index_into(self)
74    }
75
76    /// Returns the mutable reference corresponding to the key in the map.
77    #[inline]
78    pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
79        index.index_into_mut(self)
80    }
81
82    /// Gets the given key's corresponding entry in the map for insertion and/or
83    /// in-place manipulation.
84    #[inline]
85    pub fn entry(&mut self, k: Value) -> Entry {
86        match self.map.entry(k) {
87            indexmap::map::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry {
88                occupied,
89            }),
90            indexmap::map::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry {
91                vacant,
92            }),
93        }
94    }
95
96    /// Removes and returns the value corresponding to the key from the map.
97    ///
98    /// This is equivalent to [`.swap_remove(index)`][Self::swap_remove],
99    /// replacing this entry's position with the last element. If you need to
100    /// preserve the relative order of the keys in the map, use
101    /// [`.shift_remove(key)`][Self::shift_remove] instead.
102    #[inline]
103    pub fn remove<I: Index>(&mut self, index: I) -> Option<Value> {
104        self.swap_remove(index)
105    }
106
107    /// Remove and return the key-value pair.
108    ///
109    /// This is equivalent to [`.swap_remove_entry(index)`][Self::swap_remove_entry],
110    /// replacing this entry's position with the last element. If you need to
111    /// preserve the relative order of the keys in the map, use
112    /// [`.shift_remove_entry(key)`][Self::shift_remove_entry] instead.
113    #[inline]
114    pub fn remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
115        self.swap_remove_entry(index)
116    }
117
118    /// Removes and returns the value corresponding to the key from the map.
119    ///
120    /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the
121    /// last element of the map and popping it off. This perturbs the position
122    /// of what used to be the last element!
123    #[inline]
124    pub fn swap_remove<I: Index>(&mut self, index: I) -> Option<Value> {
125        index.swap_remove_from(self)
126    }
127
128    /// Remove and return the key-value pair.
129    ///
130    /// Like [`Vec::swap_remove`], the entry is removed by swapping it with the
131    /// last element of the map and popping it off. This perturbs the position
132    /// of what used to be the last element!
133    #[inline]
134    pub fn swap_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
135        index.swap_remove_entry_from(self)
136    }
137
138    /// Removes and returns the value corresponding to the key from the map.
139    ///
140    /// Like [`Vec::remove`], the entry is removed by shifting all of the
141    /// elements that follow it, preserving their relative order. This perturbs
142    /// the index of all of those elements!
143    #[inline]
144    pub fn shift_remove<I: Index>(&mut self, index: I) -> Option<Value> {
145        index.shift_remove_from(self)
146    }
147
148    /// Remove and return the key-value pair.
149    ///
150    /// Like [`Vec::remove`], the entry is removed by shifting all of the
151    /// elements that follow it, preserving their relative order. This perturbs
152    /// the index of all of those elements!
153    #[inline]
154    pub fn shift_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
155        index.shift_remove_entry_from(self)
156    }
157
158    /// Scan through each key-value pair in the map and keep those where the
159    /// closure `keep` returns true.
160    #[inline]
161    pub fn retain<F>(&mut self, keep: F)
162    where
163        F: FnMut(&Value, &mut Value) -> bool,
164    {
165        self.map.retain(keep);
166    }
167
168    /// Returns the maximum number of key-value pairs the map can hold without
169    /// reallocating.
170    #[inline]
171    pub fn capacity(&self) -> usize {
172        self.map.capacity()
173    }
174
175    /// Returns the number of key-value pairs in the map.
176    #[inline]
177    pub fn len(&self) -> usize {
178        self.map.len()
179    }
180
181    /// Returns whether the map is currently empty.
182    #[inline]
183    pub fn is_empty(&self) -> bool {
184        self.map.is_empty()
185    }
186
187    /// Clears the map of all key-value pairs.
188    #[inline]
189    pub fn clear(&mut self) {
190        self.map.clear();
191    }
192
193    /// Returns a double-ended iterator visiting all key-value pairs in order of
194    /// insertion. Iterator element type is `(&'a Value, &'a Value)`.
195    #[inline]
196    pub fn iter(&self) -> Iter {
197        Iter {
198            iter: self.map.iter(),
199        }
200    }
201
202    /// Returns a double-ended iterator visiting all key-value pairs in order of
203    /// insertion. Iterator element type is `(&'a Value, &'a mut ValuE)`.
204    #[inline]
205    pub fn iter_mut(&mut self) -> IterMut {
206        IterMut {
207            iter: self.map.iter_mut(),
208        }
209    }
210
211    /// Return an iterator over the keys of the map.
212    pub fn keys(&self) -> Keys {
213        Keys {
214            iter: self.map.keys(),
215        }
216    }
217
218    /// Return an owning iterator over the keys of the map.
219    pub fn into_keys(self) -> IntoKeys {
220        IntoKeys {
221            iter: self.map.into_keys(),
222        }
223    }
224
225    /// Return an iterator over the values of the map.
226    pub fn values(&self) -> Values {
227        Values {
228            iter: self.map.values(),
229        }
230    }
231
232    /// Return an iterator over mutable references to the values of the map.
233    pub fn values_mut(&mut self) -> ValuesMut {
234        ValuesMut {
235            iter: self.map.values_mut(),
236        }
237    }
238
239    /// Return an owning iterator over the values of the map.
240    pub fn into_values(self) -> IntoValues {
241        IntoValues {
242            iter: self.map.into_values(),
243        }
244    }
245}
246
247/// A type that can be used to index into a `serde_yaml::Mapping`. See the
248/// methods `get`, `get_mut`, `contains_key`, and `remove` of `Value`.
249///
250/// This trait is sealed and cannot be implemented for types outside of
251/// `serde_yaml`.
252pub trait Index: private::Sealed {
253    #[doc(hidden)]
254    fn is_key_into(&self, v: &Mapping) -> bool;
255
256    #[doc(hidden)]
257    fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>;
258
259    #[doc(hidden)]
260    fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>;
261
262    #[doc(hidden)]
263    fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value>;
264
265    #[doc(hidden)]
266    fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
267
268    #[doc(hidden)]
269    fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value>;
270
271    #[doc(hidden)]
272    fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
273}
274
275struct HashLikeValue<'a>(&'a str);
276
277impl<'a> indexmap::Equivalent<Value> for HashLikeValue<'a> {
278    fn equivalent(&self, key: &Value) -> bool {
279        match key {
280            Value::String(string) => self.0 == string,
281            _ => false,
282        }
283    }
284}
285
286// NOTE: This impl must be consistent with Value's Hash impl.
287impl<'a> Hash for HashLikeValue<'a> {
288    fn hash<H: Hasher>(&self, state: &mut H) {
289        const STRING: Value = Value::String(String::new());
290        mem::discriminant(&STRING).hash(state);
291        self.0.hash(state);
292    }
293}
294
295impl Index for Value {
296    fn is_key_into(&self, v: &Mapping) -> bool {
297        v.map.contains_key(self)
298    }
299    fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
300        v.map.get(self)
301    }
302    fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
303        v.map.get_mut(self)
304    }
305    fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
306        v.map.swap_remove(self)
307    }
308    fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
309        v.map.swap_remove_entry(self)
310    }
311    fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
312        v.map.shift_remove(self)
313    }
314    fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
315        v.map.shift_remove_entry(self)
316    }
317}
318
319impl Index for str {
320    fn is_key_into(&self, v: &Mapping) -> bool {
321        v.map.contains_key(&HashLikeValue(self))
322    }
323    fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
324        v.map.get(&HashLikeValue(self))
325    }
326    fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
327        v.map.get_mut(&HashLikeValue(self))
328    }
329    fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
330        v.map.swap_remove(&HashLikeValue(self))
331    }
332    fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
333        v.map.swap_remove_entry(&HashLikeValue(self))
334    }
335    fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
336        v.map.shift_remove(&HashLikeValue(self))
337    }
338    fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
339        v.map.shift_remove_entry(&HashLikeValue(self))
340    }
341}
342
343impl Index for String {
344    fn is_key_into(&self, v: &Mapping) -> bool {
345        self.as_str().is_key_into(v)
346    }
347    fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
348        self.as_str().index_into(v)
349    }
350    fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
351        self.as_str().index_into_mut(v)
352    }
353    fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
354        self.as_str().swap_remove_from(v)
355    }
356    fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
357        self.as_str().swap_remove_entry_from(v)
358    }
359    fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
360        self.as_str().shift_remove_from(v)
361    }
362    fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
363        self.as_str().shift_remove_entry_from(v)
364    }
365}
366
367impl<T> Index for &T
368where
369    T: ?Sized + Index,
370{
371    fn is_key_into(&self, v: &Mapping) -> bool {
372        (**self).is_key_into(v)
373    }
374    fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
375        (**self).index_into(v)
376    }
377    fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
378        (**self).index_into_mut(v)
379    }
380    fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
381        (**self).swap_remove_from(v)
382    }
383    fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
384        (**self).swap_remove_entry_from(v)
385    }
386    fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
387        (**self).shift_remove_from(v)
388    }
389    fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
390        (**self).shift_remove_entry_from(v)
391    }
392}
393
394#[allow(clippy::derived_hash_with_manual_eq)]
395impl Hash for Mapping {
396    fn hash<H: Hasher>(&self, state: &mut H) {
397        // Hash the kv pairs in a way that is not sensitive to their order.
398        let mut xor = 0;
399        for (k, v) in self {
400            let mut hasher = DefaultHasher::new();
401            k.hash(&mut hasher);
402            v.hash(&mut hasher);
403            xor ^= hasher.finish();
404        }
405        xor.hash(state);
406    }
407}
408
409impl PartialOrd for Mapping {
410    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
411        let mut self_entries = Vec::from_iter(self);
412        let mut other_entries = Vec::from_iter(other);
413
414        // Sort in an arbitrary order that is consistent with Value's PartialOrd
415        // impl.
416        fn total_cmp(a: &Value, b: &Value) -> Ordering {
417            match (a, b) {
418                (Value::Null, Value::Null) => Ordering::Equal,
419                (Value::Null, _) => Ordering::Less,
420                (_, Value::Null) => Ordering::Greater,
421
422                (Value::Bool(a), Value::Bool(b)) => a.cmp(b),
423                (Value::Bool(_), _) => Ordering::Less,
424                (_, Value::Bool(_)) => Ordering::Greater,
425
426                (Value::Number(a), Value::Number(b)) => a.total_cmp(b),
427                (Value::Number(_), _) => Ordering::Less,
428                (_, Value::Number(_)) => Ordering::Greater,
429
430                (Value::String(a), Value::String(b)) => a.cmp(b),
431                (Value::String(_), _) => Ordering::Less,
432                (_, Value::String(_)) => Ordering::Greater,
433
434                (Value::Sequence(a), Value::Sequence(b)) => iter_cmp_by(a, b, total_cmp),
435                (Value::Sequence(_), _) => Ordering::Less,
436                (_, Value::Sequence(_)) => Ordering::Greater,
437
438                (Value::Mapping(a), Value::Mapping(b)) => {
439                    iter_cmp_by(a, b, |(ak, av), (bk, bv)| total_cmp(ak, bk).then_with(|| total_cmp(av, bv)))
440                }
441                (Value::Mapping(_), _) => Ordering::Less,
442                (_, Value::Mapping(_)) => Ordering::Greater,
443
444                (Value::Tagged(a), Value::Tagged(b)) => a.tag.cmp(&b.tag).then_with(|| total_cmp(&a.value, &b.value)),
445            }
446        }
447
448        fn iter_cmp_by<I, F>(this: I, other: I, mut cmp: F) -> Ordering
449        where
450            I: IntoIterator,
451            F: FnMut(I::Item, I::Item) -> Ordering,
452        {
453            let mut this = this.into_iter();
454            let mut other = other.into_iter();
455
456            loop {
457                let x = match this.next() {
458                    None => {
459                        if other.next().is_none() {
460                            return Ordering::Equal;
461                        } else {
462                            return Ordering::Less;
463                        }
464                    }
465                    Some(val) => val,
466                };
467
468                let y = match other.next() {
469                    None => return Ordering::Greater,
470                    Some(val) => val,
471                };
472
473                match cmp(x, y) {
474                    Ordering::Equal => {}
475                    non_eq => return non_eq,
476                }
477            }
478        }
479
480        // While sorting by map key, we get to assume that no two keys are
481        // equal, otherwise they wouldn't both be in the map. This is not a safe
482        // assumption outside of this situation.
483        let total_cmp = |&(a, _): &_, &(b, _): &_| total_cmp(a, b);
484        self_entries.sort_by(total_cmp);
485        other_entries.sort_by(total_cmp);
486        self_entries.partial_cmp(&other_entries)
487    }
488}
489
490impl<I> std::ops::Index<I> for Mapping
491where
492    I: Index,
493{
494    type Output = Value;
495
496    #[inline]
497    #[track_caller]
498    fn index(&self, index: I) -> &Value {
499        index.index_into(self).unwrap()
500    }
501}
502
503impl<I> std::ops::IndexMut<I> for Mapping
504where
505    I: Index,
506{
507    #[inline]
508    #[track_caller]
509    fn index_mut(&mut self, index: I) -> &mut Value {
510        index.index_into_mut(self).unwrap()
511    }
512}
513
514impl Extend<(Value, Value)> for Mapping {
515    #[inline]
516    fn extend<I: IntoIterator<Item = (Value, Value)>>(&mut self, iter: I) {
517        self.map.extend(iter);
518    }
519}
520
521impl FromIterator<(Value, Value)> for Mapping {
522    #[inline]
523    fn from_iter<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self {
524        Mapping {
525            map: IndexMap::from_iter(iter),
526        }
527    }
528}
529
530macro_rules! delegate_iterator {
531    (($name:ident $($generics:tt)*) => $item:ty) => {
532        impl $($generics)* Iterator for $name $($generics)* {
533            type Item = $item;
534            #[inline]
535            fn next(&mut self) -> Option<Self::Item> {
536                self.iter.next()
537            }
538            #[inline]
539            fn size_hint(&self) -> (usize, Option<usize>) {
540                self.iter.size_hint()
541            }
542        }
543
544        impl $($generics)* ExactSizeIterator for $name $($generics)* {
545            #[inline]
546            fn len(&self) -> usize {
547                self.iter.len()
548            }
549        }
550    }
551}
552
553/// Iterator over `&serde_yaml::Mapping`.
554pub struct Iter<'a> {
555    iter: indexmap::map::Iter<'a, Value, Value>,
556}
557
558delegate_iterator!((Iter<'a>) => (&'a Value, &'a Value));
559
560impl<'a> IntoIterator for &'a Mapping {
561    type Item = (&'a Value, &'a Value);
562    type IntoIter = Iter<'a>;
563    #[inline]
564    fn into_iter(self) -> Self::IntoIter {
565        Iter {
566            iter: self.map.iter(),
567        }
568    }
569}
570
571/// Iterator over `&mut serde_yaml::Mapping`.
572pub struct IterMut<'a> {
573    iter: indexmap::map::IterMut<'a, Value, Value>,
574}
575
576delegate_iterator!((IterMut<'a>) => (&'a Value, &'a mut Value));
577
578impl<'a> IntoIterator for &'a mut Mapping {
579    type Item = (&'a Value, &'a mut Value);
580    type IntoIter = IterMut<'a>;
581    #[inline]
582    fn into_iter(self) -> Self::IntoIter {
583        IterMut {
584            iter: self.map.iter_mut(),
585        }
586    }
587}
588
589/// Iterator over `serde_yaml::Mapping` by value.
590pub struct IntoIter {
591    iter: indexmap::map::IntoIter<Value, Value>,
592}
593
594delegate_iterator!((IntoIter) => (Value, Value));
595
596impl IntoIterator for Mapping {
597    type Item = (Value, Value);
598    type IntoIter = IntoIter;
599    #[inline]
600    fn into_iter(self) -> Self::IntoIter {
601        IntoIter {
602            iter: self.map.into_iter(),
603        }
604    }
605}
606
607/// Iterator of the keys of a `&serde_yaml::Mapping`.
608pub struct Keys<'a> {
609    iter: indexmap::map::Keys<'a, Value, Value>,
610}
611
612delegate_iterator!((Keys<'a>) => &'a Value);
613
614/// Iterator of the keys of a `serde_yaml::Mapping`.
615pub struct IntoKeys {
616    iter: indexmap::map::IntoKeys<Value, Value>,
617}
618
619delegate_iterator!((IntoKeys) => Value);
620
621/// Iterator of the values of a `&serde_yaml::Mapping`.
622pub struct Values<'a> {
623    iter: indexmap::map::Values<'a, Value, Value>,
624}
625
626delegate_iterator!((Values<'a>) => &'a Value);
627
628/// Iterator of the values of a `&mut serde_yaml::Mapping`.
629pub struct ValuesMut<'a> {
630    iter: indexmap::map::ValuesMut<'a, Value, Value>,
631}
632
633delegate_iterator!((ValuesMut<'a>) => &'a mut Value);
634
635/// Iterator of the values of a `serde_yaml::Mapping`.
636pub struct IntoValues {
637    iter: indexmap::map::IntoValues<Value, Value>,
638}
639
640delegate_iterator!((IntoValues) => Value);
641
642/// Entry for an existing key-value pair or a vacant location to insert one.
643pub enum Entry<'a> {
644    /// Existing slot with equivalent key.
645    Occupied(OccupiedEntry<'a>),
646    /// Vacant slot (no equivalent key in the map).
647    Vacant(VacantEntry<'a>),
648}
649
650/// A view into an occupied entry in a [`Mapping`]. It is part of the [`Entry`]
651/// enum.
652pub struct OccupiedEntry<'a> {
653    occupied: indexmap::map::OccupiedEntry<'a, Value, Value>,
654}
655
656/// A view into a vacant entry in a [`Mapping`]. It is part of the [`Entry`]
657/// enum.
658pub struct VacantEntry<'a> {
659    vacant: indexmap::map::VacantEntry<'a, Value, Value>,
660}
661
662impl<'a> Entry<'a> {
663    /// Returns a reference to this entry's key.
664    pub fn key(&self) -> &Value {
665        match self {
666            Entry::Vacant(e) => e.key(),
667            Entry::Occupied(e) => e.key(),
668        }
669    }
670
671    /// Ensures a value is in the entry by inserting the default if empty, and
672    /// returns a mutable reference to the value in the entry.
673    pub fn or_insert(self, default: Value) -> &'a mut Value {
674        match self {
675            Entry::Vacant(entry) => entry.insert(default),
676            Entry::Occupied(entry) => entry.into_mut(),
677        }
678    }
679
680    /// Ensures a value is in the entry by inserting the result of the default
681    /// function if empty, and returns a mutable reference to the value in the
682    /// entry.
683    pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
684    where
685        F: FnOnce() -> Value,
686    {
687        match self {
688            Entry::Vacant(entry) => entry.insert(default()),
689            Entry::Occupied(entry) => entry.into_mut(),
690        }
691    }
692
693    /// Provides in-place mutable access to an occupied entry before any
694    /// potential inserts into the map.
695    pub fn and_modify<F>(self, f: F) -> Self
696    where
697        F: FnOnce(&mut Value),
698    {
699        match self {
700            Entry::Occupied(mut entry) => {
701                f(entry.get_mut());
702                Entry::Occupied(entry)
703            }
704            Entry::Vacant(entry) => Entry::Vacant(entry),
705        }
706    }
707}
708
709impl<'a> OccupiedEntry<'a> {
710    /// Gets a reference to the key in the entry.
711    #[inline]
712    pub fn key(&self) -> &Value {
713        self.occupied.key()
714    }
715
716    /// Gets a reference to the value in the entry.
717    #[inline]
718    pub fn get(&self) -> &Value {
719        self.occupied.get()
720    }
721
722    /// Gets a mutable reference to the value in the entry.
723    #[inline]
724    pub fn get_mut(&mut self) -> &mut Value {
725        self.occupied.get_mut()
726    }
727
728    /// Converts the entry into a mutable reference to its value.
729    #[inline]
730    pub fn into_mut(self) -> &'a mut Value {
731        self.occupied.into_mut()
732    }
733
734    /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns
735    /// the entry's old value.
736    #[inline]
737    pub fn insert(&mut self, value: Value) -> Value {
738        self.occupied.insert(value)
739    }
740
741    /// Takes the value of the entry out of the map, and returns it.
742    #[inline]
743    pub fn remove(self) -> Value {
744        self.occupied.swap_remove()
745    }
746
747    /// Remove and return the key, value pair stored in the map for this entry.
748    #[inline]
749    pub fn remove_entry(self) -> (Value, Value) {
750        self.occupied.swap_remove_entry()
751    }
752}
753
754impl<'a> VacantEntry<'a> {
755    /// Gets a reference to the key that would be used when inserting a value
756    /// through the VacantEntry.
757    #[inline]
758    pub fn key(&self) -> &Value {
759        self.vacant.key()
760    }
761
762    /// Takes ownership of the key, leaving the entry vacant.
763    #[inline]
764    pub fn into_key(self) -> Value {
765        self.vacant.into_key()
766    }
767
768    /// Sets the value of the entry with the VacantEntry's key, and returns a
769    /// mutable reference to it.
770    #[inline]
771    pub fn insert(self, value: Value) -> &'a mut Value {
772        self.vacant.insert(value)
773    }
774}
775
776impl Serialize for Mapping {
777    #[inline]
778    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
779        use serde::ser::SerializeMap;
780        let mut map_serializer = serializer.serialize_map(Some(self.len()))?;
781        for (k, v) in self {
782            map_serializer.serialize_entry(k, v)?;
783        }
784        map_serializer.end()
785    }
786}
787
788impl<'de> Deserialize<'de> for Mapping {
789    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
790    where
791        D: Deserializer<'de>,
792    {
793        struct Visitor;
794
795        impl<'de> serde::de::Visitor<'de> for Visitor {
796            type Value = Mapping;
797
798            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
799                formatter.write_str("a YAML mapping")
800            }
801
802            #[inline]
803            fn visit_unit<E>(self) -> Result<Self::Value, E>
804            where
805                E: serde::de::Error,
806            {
807                Ok(Mapping::new())
808            }
809
810            #[inline]
811            fn visit_map<A>(self, mut data: A) -> Result<Self::Value, A::Error>
812            where
813                A: serde::de::MapAccess<'de>,
814            {
815                let mut mapping = Mapping::new();
816
817                while let Some(key) = data.next_key()? {
818                    match mapping.entry(key) {
819                        Entry::Occupied(entry) => {
820                            return Err(serde::de::Error::custom(DuplicateKeyError {
821                                entry,
822                            }));
823                        }
824                        Entry::Vacant(entry) => {
825                            let value = data.next_value()?;
826                            entry.insert(value);
827                        }
828                    }
829                }
830
831                Ok(mapping)
832            }
833        }
834
835        deserializer.deserialize_map(Visitor)
836    }
837}
838
839struct DuplicateKeyError<'a> {
840    entry: OccupiedEntry<'a>,
841}
842
843impl<'a> Display for DuplicateKeyError<'a> {
844    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
845        formatter.write_str("duplicate entry ")?;
846        match self.entry.key() {
847            Value::Null => formatter.write_str("with null key"),
848            Value::Bool(boolean) => write!(formatter, "with key `{}`", boolean),
849            Value::Number(number) => write!(formatter, "with key {}", number),
850            Value::String(string) => write!(formatter, "with key {:?}", string),
851            Value::Sequence(_) | Value::Mapping(_) | Value::Tagged(_) => formatter.write_str("in YAML map"),
852        }
853    }
854}