serde_yaml/
mapping.rs

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