• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::mem;
11 
12 /// A YAML mapping in which the keys and values are both `serde_yaml::Value`.
13 #[derive(Clone, Default, Eq, PartialEq)]
14 pub struct Mapping {
15     map: IndexMap<Value, Value>,
16 }
17 
18 impl Mapping {
19     /// Creates an empty YAML map.
20     #[inline]
new() -> Self21     pub fn new() -> Self {
22         Self::default()
23     }
24 
25     /// Creates an empty YAML map with the given initial capacity.
26     #[inline]
with_capacity(capacity: usize) -> Self27     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]
reserve(&mut self, additional: usize)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]
shrink_to_fit(&mut self)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]
insert(&mut self, k: Value, v: Value) -> Option<Value>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]
contains_key<I: Index>(&self, index: I) -> bool62     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]
get<I: Index>(&self, index: I) -> Option<&Value>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]
get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value>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]
entry(&mut self, k: Value) -> Entry81     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]
remove<I: Index>(&mut self, index: I) -> Option<Value>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]
remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)>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]
swap_remove<I: Index>(&mut self, index: I) -> Option<Value>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]
swap_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)>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]
shift_remove<I: Index>(&mut self, index: I) -> Option<Value>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]
shift_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)>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]
retain<F>(&mut self, keep: F) where F: FnMut(&Value, &mut Value) -> bool,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]
capacity(&self) -> usize163     pub fn capacity(&self) -> usize {
164         self.map.capacity()
165     }
166 
167     /// Returns the number of key-value pairs in the map.
168     #[inline]
len(&self) -> usize169     pub fn len(&self) -> usize {
170         self.map.len()
171     }
172 
173     /// Returns whether the map is currently empty.
174     #[inline]
is_empty(&self) -> bool175     pub fn is_empty(&self) -> bool {
176         self.map.is_empty()
177     }
178 
179     /// Clears the map of all key-value pairs.
180     #[inline]
clear(&mut self)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]
iter(&self) -> Iter188     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]
iter_mut(&mut self) -> IterMut197     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.
keys(&self) -> Keys204     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.
into_keys(self) -> IntoKeys211     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.
values(&self) -> Values218     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.
values_mut(&mut self) -> ValuesMut225     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.
into_values(self) -> IntoValues232     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`.
244 pub trait Index: private::Sealed {
245     #[doc(hidden)]
is_key_into(&self, v: &Mapping) -> bool246     fn is_key_into(&self, v: &Mapping) -> bool;
247 
248     #[doc(hidden)]
index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>249     fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>;
250 
251     #[doc(hidden)]
index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>252     fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>;
253 
254     #[doc(hidden)]
swap_remove_from(&self, v: &mut Mapping) -> Option<Value>255     fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value>;
256 
257     #[doc(hidden)]
swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>258     fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
259 
260     #[doc(hidden)]
shift_remove_from(&self, v: &mut Mapping) -> Option<Value>261     fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value>;
262 
263     #[doc(hidden)]
shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>264     fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
265 }
266 
267 struct HashLikeValue<'a>(&'a str);
268 
269 impl<'a> indexmap::Equivalent<Value> for HashLikeValue<'a> {
equivalent(&self, key: &Value) -> bool270     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.
279 impl<'a> Hash for HashLikeValue<'a> {
hash<H: Hasher>(&self, state: &mut H)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 
287 impl Index for Value {
is_key_into(&self, v: &Mapping) -> bool288     fn is_key_into(&self, v: &Mapping) -> bool {
289         v.map.contains_key(self)
290     }
index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>291     fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
292         v.map.get(self)
293     }
index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>294     fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
295         v.map.get_mut(self)
296     }
swap_remove_from(&self, v: &mut Mapping) -> Option<Value>297     fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
298         v.map.swap_remove(self)
299     }
swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>300     fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
301         v.map.swap_remove_entry(self)
302     }
shift_remove_from(&self, v: &mut Mapping) -> Option<Value>303     fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
304         v.map.shift_remove(self)
305     }
shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>306     fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
307         v.map.shift_remove_entry(self)
308     }
309 }
310 
311 impl Index for str {
is_key_into(&self, v: &Mapping) -> bool312     fn is_key_into(&self, v: &Mapping) -> bool {
313         v.map.contains_key(&HashLikeValue(self))
314     }
index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>315     fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
316         v.map.get(&HashLikeValue(self))
317     }
index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>318     fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
319         v.map.get_mut(&HashLikeValue(self))
320     }
swap_remove_from(&self, v: &mut Mapping) -> Option<Value>321     fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
322         v.map.swap_remove(&HashLikeValue(self))
323     }
swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>324     fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
325         v.map.swap_remove_entry(&HashLikeValue(self))
326     }
shift_remove_from(&self, v: &mut Mapping) -> Option<Value>327     fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
328         v.map.shift_remove(&HashLikeValue(self))
329     }
shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>330     fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
331         v.map.shift_remove_entry(&HashLikeValue(self))
332     }
333 }
334 
335 impl Index for String {
is_key_into(&self, v: &Mapping) -> bool336     fn is_key_into(&self, v: &Mapping) -> bool {
337         self.as_str().is_key_into(v)
338     }
index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>339     fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
340         self.as_str().index_into(v)
341     }
index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>342     fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
343         self.as_str().index_into_mut(v)
344     }
swap_remove_from(&self, v: &mut Mapping) -> Option<Value>345     fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
346         self.as_str().swap_remove_from(v)
347     }
swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>348     fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
349         self.as_str().swap_remove_entry_from(v)
350     }
shift_remove_from(&self, v: &mut Mapping) -> Option<Value>351     fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
352         self.as_str().shift_remove_from(v)
353     }
shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>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 
359 impl<T> Index for &T
360 where
361     T: ?Sized + Index,
362 {
is_key_into(&self, v: &Mapping) -> bool363     fn is_key_into(&self, v: &Mapping) -> bool {
364         (**self).is_key_into(v)
365     }
index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>366     fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
367         (**self).index_into(v)
368     }
index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>369     fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
370         (**self).index_into_mut(v)
371     }
swap_remove_from(&self, v: &mut Mapping) -> Option<Value>372     fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
373         (**self).swap_remove_from(v)
374     }
swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>375     fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
376         (**self).swap_remove_entry_from(v)
377     }
shift_remove_from(&self, v: &mut Mapping) -> Option<Value>378     fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
379         (**self).shift_remove_from(v)
380     }
shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>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)]
387 impl Hash for Mapping {
hash<H: Hasher>(&self, state: &mut H)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 
401 impl PartialOrd for Mapping {
partial_cmp(&self, other: &Self) -> Option<Ordering>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 
487 impl<I> std::ops::Index<I> for Mapping
488 where
489     I: Index,
490 {
491     type Output = Value;
492 
493     #[inline]
494     #[track_caller]
index(&self, index: I) -> &Value495     fn index(&self, index: I) -> &Value {
496         index.index_into(self).unwrap()
497     }
498 }
499 
500 impl<I> std::ops::IndexMut<I> for Mapping
501 where
502     I: Index,
503 {
504     #[inline]
505     #[track_caller]
index_mut(&mut self, index: I) -> &mut Value506     fn index_mut(&mut self, index: I) -> &mut Value {
507         index.index_into_mut(self).unwrap()
508     }
509 }
510 
511 impl Extend<(Value, Value)> for Mapping {
512     #[inline]
extend<I: IntoIterator<Item = (Value, Value)>>(&mut self, iter: I)513     fn extend<I: IntoIterator<Item = (Value, Value)>>(&mut self, iter: I) {
514         self.map.extend(iter);
515     }
516 }
517 
518 impl FromIterator<(Value, Value)> for Mapping {
519     #[inline]
from_iter<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self520     fn from_iter<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self {
521         Mapping {
522             map: IndexMap::from_iter(iter),
523         }
524     }
525 }
526 
527 macro_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`.
551 pub struct Iter<'a> {
552     iter: indexmap::map::Iter<'a, Value, Value>,
553 }
554 
555 delegate_iterator!((Iter<'a>) => (&'a Value, &'a Value));
556 
557 impl<'a> IntoIterator for &'a Mapping {
558     type Item = (&'a Value, &'a Value);
559     type IntoIter = Iter<'a>;
560     #[inline]
into_iter(self) -> Self::IntoIter561     fn into_iter(self) -> Self::IntoIter {
562         Iter {
563             iter: self.map.iter(),
564         }
565     }
566 }
567 
568 /// Iterator over `&mut serde_yaml::Mapping`.
569 pub struct IterMut<'a> {
570     iter: indexmap::map::IterMut<'a, Value, Value>,
571 }
572 
573 delegate_iterator!((IterMut<'a>) => (&'a Value, &'a mut Value));
574 
575 impl<'a> IntoIterator for &'a mut Mapping {
576     type Item = (&'a Value, &'a mut Value);
577     type IntoIter = IterMut<'a>;
578     #[inline]
into_iter(self) -> Self::IntoIter579     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.
587 pub struct IntoIter {
588     iter: indexmap::map::IntoIter<Value, Value>,
589 }
590 
591 delegate_iterator!((IntoIter) => (Value, Value));
592 
593 impl IntoIterator for Mapping {
594     type Item = (Value, Value);
595     type IntoIter = IntoIter;
596     #[inline]
into_iter(self) -> Self::IntoIter597     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`.
605 pub struct Keys<'a> {
606     iter: indexmap::map::Keys<'a, Value, Value>,
607 }
608 
609 delegate_iterator!((Keys<'a>) => &'a Value);
610 
611 /// Iterator of the keys of a `serde_yaml::Mapping`.
612 pub struct IntoKeys {
613     iter: indexmap::map::IntoKeys<Value, Value>,
614 }
615 
616 delegate_iterator!((IntoKeys) => Value);
617 
618 /// Iterator of the values of a `&serde_yaml::Mapping`.
619 pub struct Values<'a> {
620     iter: indexmap::map::Values<'a, Value, Value>,
621 }
622 
623 delegate_iterator!((Values<'a>) => &'a Value);
624 
625 /// Iterator of the values of a `&mut serde_yaml::Mapping`.
626 pub struct ValuesMut<'a> {
627     iter: indexmap::map::ValuesMut<'a, Value, Value>,
628 }
629 
630 delegate_iterator!((ValuesMut<'a>) => &'a mut Value);
631 
632 /// Iterator of the values of a `serde_yaml::Mapping`.
633 pub struct IntoValues {
634     iter: indexmap::map::IntoValues<Value, Value>,
635 }
636 
637 delegate_iterator!((IntoValues) => Value);
638 
639 /// Entry for an existing key-value pair or a vacant location to insert one.
640 pub 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.
649 pub 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.
655 pub struct VacantEntry<'a> {
656     vacant: indexmap::map::VacantEntry<'a, Value, Value>,
657 }
658 
659 impl<'a> Entry<'a> {
660     /// Returns a reference to this entry's key.
key(&self) -> &Value661     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.
or_insert(self, default: Value) -> &'a mut Value670     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.
or_insert_with<F>(self, default: F) -> &'a mut Value where F: FnOnce() -> Value,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.
and_modify<F>(self, f: F) -> Self where F: FnOnce(&mut Value),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 
706 impl<'a> OccupiedEntry<'a> {
707     /// Gets a reference to the key in the entry.
708     #[inline]
key(&self) -> &Value709     pub fn key(&self) -> &Value {
710         self.occupied.key()
711     }
712 
713     /// Gets a reference to the value in the entry.
714     #[inline]
get(&self) -> &Value715     pub fn get(&self) -> &Value {
716         self.occupied.get()
717     }
718 
719     /// Gets a mutable reference to the value in the entry.
720     #[inline]
get_mut(&mut self) -> &mut Value721     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]
into_mut(self) -> &'a mut Value727     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]
insert(&mut self, value: Value) -> Value734     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]
remove(self) -> Value740     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]
remove_entry(self) -> (Value, Value)746     pub fn remove_entry(self) -> (Value, Value) {
747         self.occupied.swap_remove_entry()
748     }
749 }
750 
751 impl<'a> VacantEntry<'a> {
752     /// Gets a reference to the key that would be used when inserting a value
753     /// through the VacantEntry.
754     #[inline]
key(&self) -> &Value755     pub fn key(&self) -> &Value {
756         self.vacant.key()
757     }
758 
759     /// Takes ownership of the key, leaving the entry vacant.
760     #[inline]
into_key(self) -> Value761     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]
insert(self, value: Value) -> &'a mut Value768     pub fn insert(self, value: Value) -> &'a mut Value {
769         self.vacant.insert(value)
770     }
771 }
772 
773 impl Serialize for Mapping {
774     #[inline]
serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>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 
785 impl<'de> Deserialize<'de> for Mapping {
deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de>,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 
834 struct DuplicateKeyError<'a> {
835     entry: OccupiedEntry<'a>,
836 }
837 
838 impl<'a> Display for DuplicateKeyError<'a> {
fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result839     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 }
852