Skip to main content

yaml_rt_serde/value/
mapping.rs

1use std::cmp::Ordering;
2use std::collections::hash_map::DefaultHasher;
3use std::fmt;
4use std::hash::{Hash, Hasher};
5use std::iter::FusedIterator;
6use std::ops;
7
8use serde::de::{Error as _, MapAccess, Visitor};
9use serde::ser::SerializeMap;
10use serde::{Deserialize, Deserializer, Serialize, Serializer};
11
12use super::{Index, Value};
13
14/// An insertion-ordered YAML mapping whose keys and values are both [`Value`].
15#[derive(Clone, Default)]
16pub struct Mapping {
17    pub(crate) entries: Vec<(Value, Value)>,
18}
19
20impl Mapping {
21    /// Creates an empty mapping.
22    #[must_use]
23    pub const fn new() -> Self {
24        Self {
25            entries: Vec::new(),
26        }
27    }
28
29    /// Creates an empty mapping with space for at least `capacity` entries.
30    #[must_use]
31    pub fn with_capacity(capacity: usize) -> Self {
32        Self {
33            entries: Vec::with_capacity(capacity),
34        }
35    }
36
37    /// Reserves capacity for at least `additional` more entries.
38    pub fn reserve(&mut self, additional: usize) {
39        self.entries.reserve(additional);
40    }
41
42    /// Shrinks the mapping's allocation as much as possible.
43    pub fn shrink_to_fit(&mut self) {
44        self.entries.shrink_to_fit();
45    }
46
47    /// Returns the allocated entry capacity.
48    #[must_use]
49    pub fn capacity(&self) -> usize {
50        self.entries.capacity()
51    }
52
53    /// Returns the number of entries.
54    #[must_use]
55    pub fn len(&self) -> usize {
56        self.entries.len()
57    }
58
59    /// Returns true when there are no entries.
60    #[must_use]
61    pub fn is_empty(&self) -> bool {
62        self.entries.is_empty()
63    }
64
65    /// Removes all entries.
66    pub fn clear(&mut self) {
67        self.entries.clear();
68    }
69
70    /// Inserts an entry, returning the previous value when the key existed.
71    pub fn insert(&mut self, key: Value, value: Value) -> Option<Value> {
72        if let Some(index) = self.position(&key) {
73            return Some(std::mem::replace(&mut self.entries[index].1, value));
74        }
75        self.entries.push((key, value));
76        None
77    }
78
79    pub(crate) fn position(&self, key: &Value) -> Option<usize> {
80        self.entries
81            .iter()
82            .position(|(candidate, _)| candidate == key)
83    }
84
85    /// Returns whether the mapping contains `index`.
86    #[must_use]
87    pub fn contains_key<I>(&self, index: I) -> bool
88    where
89        I: Index,
90    {
91        index.mapping_position(self).is_some()
92    }
93
94    /// Returns the value selected by `index`.
95    #[must_use]
96    pub fn get<I>(&self, index: I) -> Option<&Value>
97    where
98        I: Index,
99    {
100        index
101            .mapping_position(self)
102            .map(|position| &self.entries[position].1)
103    }
104
105    /// Returns a mutable value selected by `index`.
106    pub fn get_mut<I>(&mut self, index: I) -> Option<&mut Value>
107    where
108        I: Index,
109    {
110        let position = index.mapping_position(self)?;
111        Some(&mut self.entries[position].1)
112    }
113
114    /// Returns the entry API for `key`.
115    pub fn entry(&mut self, key: Value) -> Entry<'_> {
116        match self.position(&key) {
117            Some(index) => Entry::Occupied(OccupiedEntry {
118                mapping: self,
119                index,
120            }),
121            None => Entry::Vacant(VacantEntry { mapping: self, key }),
122        }
123    }
124
125    /// Removes an entry by swapping the last entry into its position.
126    pub fn remove<I>(&mut self, index: I) -> Option<Value>
127    where
128        I: Index,
129    {
130        self.swap_remove(index)
131    }
132
133    /// Removes and returns an entry by swapping the last entry into its position.
134    pub fn remove_entry<I>(&mut self, index: I) -> Option<(Value, Value)>
135    where
136        I: Index,
137    {
138        self.swap_remove_entry(index)
139    }
140
141    /// Removes a value by swapping the last entry into its position.
142    pub fn swap_remove<I>(&mut self, index: I) -> Option<Value>
143    where
144        I: Index,
145    {
146        self.swap_remove_entry(index).map(|(_, value)| value)
147    }
148
149    /// Removes an entry by swapping the last entry into its position.
150    pub fn swap_remove_entry<I>(&mut self, index: I) -> Option<(Value, Value)>
151    where
152        I: Index,
153    {
154        let position = index.mapping_position(self)?;
155        Some(self.entries.swap_remove(position))
156    }
157
158    /// Removes a value while retaining the relative order of other entries.
159    pub fn shift_remove<I>(&mut self, index: I) -> Option<Value>
160    where
161        I: Index,
162    {
163        self.shift_remove_entry(index).map(|(_, value)| value)
164    }
165
166    /// Removes an entry while retaining the relative order of other entries.
167    pub fn shift_remove_entry<I>(&mut self, index: I) -> Option<(Value, Value)>
168    where
169        I: Index,
170    {
171        let position = index.mapping_position(self)?;
172        Some(self.entries.remove(position))
173    }
174
175    /// Retains only entries for which `keep` returns true.
176    pub fn retain<F>(&mut self, mut keep: F)
177    where
178        F: FnMut(&Value, &mut Value) -> bool,
179    {
180        self.entries.retain_mut(|(key, value)| keep(key, value));
181    }
182
183    /// Iterates over entries in insertion order.
184    pub fn iter(&self) -> Iter<'_> {
185        Iter(self.entries.iter())
186    }
187
188    /// Mutably iterates over entries in insertion order.
189    pub fn iter_mut(&mut self) -> IterMut<'_> {
190        IterMut(self.entries.iter_mut())
191    }
192
193    /// Iterates over keys in insertion order.
194    pub fn keys(&self) -> Keys<'_> {
195        Keys(self.iter())
196    }
197
198    /// Iterates over values in insertion order.
199    pub fn values(&self) -> Values<'_> {
200        Values(self.iter())
201    }
202
203    /// Mutably iterates over values in insertion order.
204    pub fn values_mut(&mut self) -> ValuesMut<'_> {
205        ValuesMut(self.iter_mut())
206    }
207
208    /// Consumes the mapping and iterates over its keys.
209    pub fn into_keys(self) -> IntoKeys {
210        IntoKeys(self.entries.into_iter())
211    }
212
213    /// Consumes the mapping and iterates over its values.
214    pub fn into_values(self) -> IntoValues {
215        IntoValues(self.entries.into_iter())
216    }
217}
218
219impl fmt::Debug for Mapping {
220    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
221        formatter.debug_map().entries(self.iter()).finish()
222    }
223}
224
225impl PartialEq for Mapping {
226    fn eq(&self, other: &Self) -> bool {
227        self.len() == other.len()
228            && self
229                .iter()
230                .all(|(key, value)| other.get(key).is_some_and(|other| other == value))
231    }
232}
233
234impl Eq for Mapping {}
235
236impl PartialOrd for Mapping {
237    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
238        if self == other {
239            Some(Ordering::Equal)
240        } else {
241            self.entries.partial_cmp(&other.entries)
242        }
243    }
244}
245
246impl Hash for Mapping {
247    fn hash<H: Hasher>(&self, state: &mut H) {
248        let mut entry_hashes = Vec::with_capacity(self.len());
249        for entry in &self.entries {
250            let mut hasher = DefaultHasher::new();
251            entry.hash(&mut hasher);
252            entry_hashes.push(hasher.finish());
253        }
254        entry_hashes.sort_unstable();
255        self.len().hash(state);
256        entry_hashes.hash(state);
257    }
258}
259
260impl Serialize for Mapping {
261    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
262    where
263        S: Serializer,
264    {
265        let mut mapping = serializer.serialize_map(Some(self.len()))?;
266        for (key, value) in self {
267            mapping.serialize_entry(key, value)?;
268        }
269        mapping.end()
270    }
271}
272
273impl<'de> Deserialize<'de> for Mapping {
274    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
275    where
276        D: Deserializer<'de>,
277    {
278        struct MappingVisitor;
279
280        impl<'de> Visitor<'de> for MappingVisitor {
281            type Value = Mapping;
282
283            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
284                formatter.write_str("a YAML mapping")
285            }
286
287            fn visit_map<A>(self, mut access: A) -> Result<Mapping, A::Error>
288            where
289                A: MapAccess<'de>,
290            {
291                let mut mapping = Mapping::with_capacity(access.size_hint().unwrap_or(0));
292                while let Some((key, value)) = access.next_entry()? {
293                    if mapping.insert(key, value).is_some() {
294                        return Err(A::Error::custom("duplicate mapping key"));
295                    }
296                }
297                Ok(mapping)
298            }
299        }
300
301        deserializer.deserialize_map(MappingVisitor)
302    }
303}
304
305impl Extend<(Value, Value)> for Mapping {
306    fn extend<T>(&mut self, iter: T)
307    where
308        T: IntoIterator<Item = (Value, Value)>,
309    {
310        for (key, value) in iter {
311            self.insert(key, value);
312        }
313    }
314}
315
316impl FromIterator<(Value, Value)> for Mapping {
317    fn from_iter<T>(iter: T) -> Self
318    where
319        T: IntoIterator<Item = (Value, Value)>,
320    {
321        let mut mapping = Self::new();
322        mapping.extend(iter);
323        mapping
324    }
325}
326
327impl<I> ops::Index<I> for Mapping
328where
329    I: Index,
330{
331    type Output = Value;
332
333    fn index(&self, index: I) -> &Self::Output {
334        self.get(index).expect("no entry found for key")
335    }
336}
337
338impl<I> ops::IndexMut<I> for Mapping
339where
340    I: Index,
341{
342    fn index_mut(&mut self, index: I) -> &mut Self::Output {
343        self.get_mut(index).expect("no entry found for key")
344    }
345}
346
347/// A view into an occupied or vacant mapping entry.
348pub enum Entry<'a> {
349    /// An existing entry.
350    Occupied(OccupiedEntry<'a>),
351    /// A missing entry.
352    Vacant(VacantEntry<'a>),
353}
354
355impl<'a> Entry<'a> {
356    /// Returns the entry's key.
357    #[must_use]
358    pub fn key(&self) -> &Value {
359        match self {
360            Self::Occupied(entry) => entry.key(),
361            Self::Vacant(entry) => entry.key(),
362        }
363    }
364
365    /// Ensures a value is present and returns a mutable reference to it.
366    pub fn or_insert(self, default: Value) -> &'a mut Value {
367        match self {
368            Self::Occupied(entry) => entry.into_mut(),
369            Self::Vacant(entry) => entry.insert(default),
370        }
371    }
372
373    /// Ensures a lazily produced value is present.
374    pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
375    where
376        F: FnOnce() -> Value,
377    {
378        match self {
379            Self::Occupied(entry) => entry.into_mut(),
380            Self::Vacant(entry) => entry.insert(default()),
381        }
382    }
383
384    /// Modifies an occupied entry before returning it.
385    pub fn and_modify<F>(mut self, modify: F) -> Self
386    where
387        F: FnOnce(&mut Value),
388    {
389        if let Self::Occupied(entry) = &mut self {
390            modify(entry.get_mut());
391        }
392        self
393    }
394}
395
396/// An occupied mapping entry.
397pub struct OccupiedEntry<'a> {
398    mapping: &'a mut Mapping,
399    index: usize,
400}
401
402impl<'a> OccupiedEntry<'a> {
403    /// Returns the entry's key.
404    #[must_use]
405    pub fn key(&self) -> &Value {
406        &self.mapping.entries[self.index].0
407    }
408
409    /// Returns the entry's value.
410    #[must_use]
411    pub fn get(&self) -> &Value {
412        &self.mapping.entries[self.index].1
413    }
414
415    /// Returns a mutable entry value.
416    pub fn get_mut(&mut self) -> &mut Value {
417        &mut self.mapping.entries[self.index].1
418    }
419
420    /// Converts this entry into a mutable value reference.
421    pub fn into_mut(self) -> &'a mut Value {
422        &mut self.mapping.entries[self.index].1
423    }
424
425    /// Replaces and returns the old value.
426    pub fn insert(&mut self, value: Value) -> Value {
427        std::mem::replace(self.get_mut(), value)
428    }
429
430    /// Removes and returns the value using swap removal.
431    pub fn remove(self) -> Value {
432        self.remove_entry().1
433    }
434
435    /// Removes and returns the entry using swap removal.
436    pub fn remove_entry(self) -> (Value, Value) {
437        self.mapping.entries.swap_remove(self.index)
438    }
439}
440
441/// A vacant mapping entry.
442pub struct VacantEntry<'a> {
443    mapping: &'a mut Mapping,
444    key: Value,
445}
446
447impl<'a> VacantEntry<'a> {
448    /// Returns the entry's key.
449    #[must_use]
450    pub fn key(&self) -> &Value {
451        &self.key
452    }
453
454    /// Consumes and returns the entry's key.
455    #[must_use]
456    pub fn into_key(self) -> Value {
457        self.key
458    }
459
460    /// Inserts a value and returns a mutable reference to it.
461    pub fn insert(self, value: Value) -> &'a mut Value {
462        self.mapping.entries.push((self.key, value));
463        &mut self
464            .mapping
465            .entries
466            .last_mut()
467            .expect("entry was inserted")
468            .1
469    }
470}
471
472/// Immutable mapping iterator.
473#[derive(Clone)]
474pub struct Iter<'a>(std::slice::Iter<'a, (Value, Value)>);
475
476impl<'a> Iterator for Iter<'a> {
477    type Item = (&'a Value, &'a Value);
478
479    fn next(&mut self) -> Option<Self::Item> {
480        self.0.next().map(|(key, value)| (key, value))
481    }
482
483    fn size_hint(&self) -> (usize, Option<usize>) {
484        self.0.size_hint()
485    }
486}
487
488impl DoubleEndedIterator for Iter<'_> {
489    fn next_back(&mut self) -> Option<Self::Item> {
490        self.0.next_back().map(|(key, value)| (key, value))
491    }
492}
493
494impl ExactSizeIterator for Iter<'_> {}
495impl FusedIterator for Iter<'_> {}
496
497/// Mutable mapping iterator.
498pub struct IterMut<'a>(std::slice::IterMut<'a, (Value, Value)>);
499
500impl<'a> Iterator for IterMut<'a> {
501    type Item = (&'a Value, &'a mut Value);
502
503    fn next(&mut self) -> Option<Self::Item> {
504        self.0.next().map(|(key, value)| (&*key, value))
505    }
506
507    fn size_hint(&self) -> (usize, Option<usize>) {
508        self.0.size_hint()
509    }
510}
511
512impl DoubleEndedIterator for IterMut<'_> {
513    fn next_back(&mut self) -> Option<Self::Item> {
514        self.0.next_back().map(|(key, value)| (&*key, value))
515    }
516}
517
518impl ExactSizeIterator for IterMut<'_> {}
519impl FusedIterator for IterMut<'_> {}
520
521macro_rules! iterator_wrapper {
522    ($name:ident, $inner:ty, $item:ty, $map:expr) => {
523        pub struct $name<'a>($inner);
524
525        impl<'a> Iterator for $name<'a> {
526            type Item = $item;
527
528            fn next(&mut self) -> Option<Self::Item> {
529                self.0.next().map($map)
530            }
531
532            fn size_hint(&self) -> (usize, Option<usize>) {
533                self.0.size_hint()
534            }
535        }
536
537        impl DoubleEndedIterator for $name<'_> {
538            fn next_back(&mut self) -> Option<Self::Item> {
539                self.0.next_back().map($map)
540            }
541        }
542
543        impl ExactSizeIterator for $name<'_> {}
544        impl FusedIterator for $name<'_> {}
545    };
546}
547
548iterator_wrapper!(Keys, Iter<'a>, &'a Value, |(key, _)| key);
549iterator_wrapper!(Values, Iter<'a>, &'a Value, |(_, value)| value);
550iterator_wrapper!(ValuesMut, IterMut<'a>, &'a mut Value, |(_, value)| value);
551
552/// Owning mapping iterator.
553pub type IntoIter = std::vec::IntoIter<(Value, Value)>;
554
555/// Owning key iterator.
556pub struct IntoKeys(IntoIter);
557
558impl Iterator for IntoKeys {
559    type Item = Value;
560
561    fn next(&mut self) -> Option<Self::Item> {
562        self.0.next().map(|(key, _)| key)
563    }
564
565    fn size_hint(&self) -> (usize, Option<usize>) {
566        self.0.size_hint()
567    }
568}
569
570impl DoubleEndedIterator for IntoKeys {
571    fn next_back(&mut self) -> Option<Self::Item> {
572        self.0.next_back().map(|(key, _)| key)
573    }
574}
575
576impl ExactSizeIterator for IntoKeys {}
577impl FusedIterator for IntoKeys {}
578
579/// Owning value iterator.
580pub struct IntoValues(IntoIter);
581
582impl Iterator for IntoValues {
583    type Item = Value;
584
585    fn next(&mut self) -> Option<Self::Item> {
586        self.0.next().map(|(_, value)| value)
587    }
588
589    fn size_hint(&self) -> (usize, Option<usize>) {
590        self.0.size_hint()
591    }
592}
593
594impl DoubleEndedIterator for IntoValues {
595    fn next_back(&mut self) -> Option<Self::Item> {
596        self.0.next_back().map(|(_, value)| value)
597    }
598}
599
600impl ExactSizeIterator for IntoValues {}
601impl FusedIterator for IntoValues {}
602
603impl IntoIterator for Mapping {
604    type Item = (Value, Value);
605    type IntoIter = IntoIter;
606
607    fn into_iter(self) -> Self::IntoIter {
608        self.entries.into_iter()
609    }
610}
611
612impl<'a> IntoIterator for &'a Mapping {
613    type Item = (&'a Value, &'a Value);
614    type IntoIter = Iter<'a>;
615
616    fn into_iter(self) -> Self::IntoIter {
617        self.iter()
618    }
619}
620
621impl<'a> IntoIterator for &'a mut Mapping {
622    type Item = (&'a Value, &'a mut Value);
623    type IntoIter = IterMut<'a>;
624
625    fn into_iter(self) -> Self::IntoIter {
626        self.iter_mut()
627    }
628}