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