toml/
map.rs

1// Copyright 2017 Serde Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! A map of `String` to [Value][crate::Value].
10//!
11//! By default the map is backed by a [`BTreeMap`]. Enable the `preserve_order`
12//! feature of toml-rs to use [`IndexMap`] instead.
13//!
14//! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
15//! [`IndexMap`]: https://docs.rs/indexmap
16
17#[cfg(not(feature = "preserve_order"))]
18use alloc::collections::{btree_map, BTreeMap};
19use core::borrow::Borrow;
20use core::fmt::{self, Debug};
21use core::hash::Hash;
22use core::iter::FromIterator;
23use core::ops;
24
25#[cfg(feature = "preserve_order")]
26use indexmap::{self, IndexMap};
27
28/// Represents a TOML key/value type.
29pub struct Map<K, V> {
30    map: MapImpl<K, V>,
31    dotted: bool,
32    implicit: bool,
33    inline: bool,
34}
35
36#[cfg(not(feature = "preserve_order"))]
37type MapImpl<K, V> = BTreeMap<K, V>;
38#[cfg(all(feature = "preserve_order", not(feature = "fast_hash")))]
39type RandomState = std::collections::hash_map::RandomState;
40#[cfg(all(feature = "preserve_order", feature = "fast_hash"))]
41type RandomState = foldhash::fast::RandomState;
42#[cfg(feature = "preserve_order")]
43type MapImpl<K, V> = IndexMap<K, V, RandomState>;
44
45impl<K, V> Map<K, V>
46where
47    K: Ord + Hash,
48{
49    /// Makes a new empty Map.
50    #[inline]
51    pub fn new() -> Self {
52        Self {
53            #[cfg(feature = "preserve_order")]
54            map: MapImpl::with_hasher(RandomState::default()),
55            #[cfg(not(feature = "preserve_order"))]
56            map: MapImpl::new(),
57            dotted: false,
58            implicit: false,
59            inline: false,
60        }
61    }
62
63    #[cfg(not(feature = "preserve_order"))]
64    /// Makes a new empty Map with the given initial capacity.
65    #[inline]
66    pub fn with_capacity(capacity: usize) -> Self {
67        // does not support with_capacity
68        let _ = capacity;
69        Self::new()
70    }
71
72    #[cfg(feature = "preserve_order")]
73    /// Makes a new empty Map with the given initial capacity.
74    #[inline]
75    pub fn with_capacity(capacity: usize) -> Self {
76        Self {
77            map: IndexMap::with_capacity_and_hasher(capacity, RandomState::default()),
78            dotted: false,
79            implicit: false,
80            inline: false,
81        }
82    }
83
84    /// Clears the map, removing all values.
85    #[inline]
86    pub fn clear(&mut self) {
87        self.map.clear();
88    }
89
90    /// Returns a reference to the value corresponding to the key.
91    ///
92    /// The key may be any borrowed form of the map's key type, but the ordering
93    /// on the borrowed form *must* match the ordering on the key type.
94    #[inline]
95    pub fn get<Q>(&self, key: &Q) -> Option<&V>
96    where
97        K: Borrow<Q>,
98        Q: Ord + Eq + Hash + ?Sized,
99    {
100        self.map.get(key)
101    }
102
103    /// Returns true if the map contains a value for the specified key.
104    ///
105    /// The key may be any borrowed form of the map's key type, but the ordering
106    /// on the borrowed form *must* match the ordering on the key type.
107    #[inline]
108    pub fn contains_key<Q>(&self, key: &Q) -> bool
109    where
110        K: Borrow<Q>,
111        Q: Ord + Eq + Hash + ?Sized,
112    {
113        self.map.contains_key(key)
114    }
115
116    /// Returns a mutable reference to the value corresponding to the key.
117    ///
118    /// The key may be any borrowed form of the map's key type, but the ordering
119    /// on the borrowed form *must* match the ordering on the key type.
120    #[inline]
121    pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
122    where
123        K: Borrow<Q>,
124        Q: Ord + Eq + Hash + ?Sized,
125    {
126        self.map.get_mut(key)
127    }
128
129    /// Returns the key-value pair matching the given key.
130    ///
131    /// The key may be any borrowed form of the map's key type, but the ordering
132    /// on the borrowed form *must* match the ordering on the key type.
133    #[inline]
134    pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
135    where
136        K: Borrow<Q>,
137        Q: ?Sized + Ord + Eq + Hash,
138    {
139        self.map.get_key_value(key)
140    }
141
142    /// Inserts a key-value pair into the map.
143    ///
144    /// If the map did not have this key present, `None` is returned.
145    ///
146    /// If the map did have this key present, the value is updated, and the old
147    /// value is returned. The key is not updated, though; this matters for
148    /// types that can be `==` without being identical.
149    #[inline]
150    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
151        self.map.insert(k, v)
152    }
153
154    /// Removes a key from the map, returning the value at the key if the key
155    /// was previously in the map.
156    ///
157    /// The key may be any borrowed form of the map's key type, but the ordering
158    /// on the borrowed form *must* match the ordering on the key type.
159    #[inline]
160    pub fn remove<Q>(&mut self, key: &Q) -> Option<V>
161    where
162        K: Borrow<Q>,
163        Q: Ord + Eq + Hash + ?Sized,
164    {
165        #[cfg(not(feature = "preserve_order"))]
166        {
167            self.map.remove(key)
168        }
169        #[cfg(feature = "preserve_order")]
170        {
171            self.map.shift_remove(key)
172        }
173    }
174
175    /// Removes a key from the map, returning the stored key and value if the key was previously in the map.
176    #[inline]
177    pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
178    where
179        K: Borrow<Q>,
180        Q: Ord + Eq + Hash + ?Sized,
181    {
182        #[cfg(not(feature = "preserve_order"))]
183        {
184            self.map.remove_entry(key)
185        }
186        #[cfg(feature = "preserve_order")]
187        {
188            self.map.shift_remove_entry(key)
189        }
190    }
191
192    /// Retains only the elements specified by the `keep` predicate.
193    ///
194    /// In other words, remove all pairs `(k, v)` for which `keep(&k, &mut v)`
195    /// returns `false`.
196    ///
197    /// The elements are visited in iteration order.
198    #[inline]
199    pub fn retain<F>(&mut self, mut keep: F)
200    where
201        K: AsRef<str>,
202        F: FnMut(&str, &mut V) -> bool,
203    {
204        self.map.retain(|key, value| keep(key.as_ref(), value));
205    }
206
207    /// Gets the given key's corresponding entry in the map for in-place
208    /// manipulation.
209    pub fn entry<S>(&mut self, key: S) -> Entry<'_, K, V>
210    where
211        S: Into<K>,
212    {
213        #[cfg(not(feature = "preserve_order"))]
214        use alloc::collections::btree_map::Entry as EntryImpl;
215        #[cfg(feature = "preserve_order")]
216        use indexmap::map::Entry as EntryImpl;
217
218        match self.map.entry(key.into()) {
219            EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
220            EntryImpl::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
221        }
222    }
223
224    /// Returns the number of elements in the map.
225    #[inline]
226    pub fn len(&self) -> usize {
227        self.map.len()
228    }
229
230    /// Returns true if the map contains no elements.
231    #[inline]
232    pub fn is_empty(&self) -> bool {
233        self.map.is_empty()
234    }
235
236    /// Gets an iterator over the entries of the map.
237    #[inline]
238    pub fn iter(&self) -> Iter<'_, K, V> {
239        Iter {
240            iter: self.map.iter(),
241        }
242    }
243
244    /// Gets a mutable iterator over the entries of the map.
245    #[inline]
246    pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
247        IterMut {
248            iter: self.map.iter_mut(),
249        }
250    }
251
252    /// Gets an iterator over the keys of the map.
253    #[inline]
254    pub fn keys(&self) -> Keys<'_, K, V> {
255        Keys {
256            iter: self.map.keys(),
257        }
258    }
259
260    /// Gets an iterator over the values of the map.
261    #[inline]
262    pub fn values(&self) -> Values<'_, K, V> {
263        Values {
264            iter: self.map.values(),
265        }
266    }
267
268    /// Scan through each key-value pair in the map and keep those where the
269    /// closure `keep` returns `true`.
270    ///
271    /// The elements are visited in order, and remaining elements keep their
272    /// order.
273    ///
274    /// Computes in **O(n)** time (average).
275    #[allow(unused_mut)]
276    pub(crate) fn mut_entries<F>(&mut self, mut op: F)
277    where
278        F: FnMut(&mut K, &mut V),
279    {
280        #[cfg(feature = "preserve_order")]
281        {
282            use indexmap::map::MutableKeys as _;
283            for (key, value) in self.map.iter_mut2() {
284                op(key, value);
285            }
286        }
287        #[cfg(not(feature = "preserve_order"))]
288        {
289            self.map = core::mem::take(&mut self.map)
290                .into_iter()
291                .map(move |(mut k, mut v)| {
292                    op(&mut k, &mut v);
293                    (k, v)
294                })
295                .collect();
296        }
297    }
298}
299
300impl<K, V> Map<K, V>
301where
302    K: Ord,
303{
304    pub(crate) fn is_dotted(&self) -> bool {
305        self.dotted
306    }
307
308    pub(crate) fn is_implicit(&self) -> bool {
309        self.implicit
310    }
311
312    pub(crate) fn is_inline(&self) -> bool {
313        self.inline
314    }
315
316    pub(crate) fn set_implicit(&mut self, yes: bool) {
317        self.implicit = yes;
318    }
319
320    pub(crate) fn set_dotted(&mut self, yes: bool) {
321        self.dotted = yes;
322    }
323
324    pub(crate) fn set_inline(&mut self, yes: bool) {
325        self.inline = yes;
326    }
327}
328
329impl<K, V> Default for Map<K, V>
330where
331    K: Ord + Hash,
332{
333    #[inline]
334    fn default() -> Self {
335        Self::new()
336    }
337}
338
339impl<K: Clone, V: Clone> Clone for Map<K, V> {
340    #[inline]
341    fn clone(&self) -> Self {
342        Self {
343            map: self.map.clone(),
344            dotted: self.dotted,
345            implicit: self.implicit,
346            inline: self.inline,
347        }
348    }
349}
350
351impl<K: Eq + Hash, V: PartialEq> PartialEq for Map<K, V> {
352    #[inline]
353    fn eq(&self, other: &Self) -> bool {
354        self.map.eq(&other.map)
355    }
356}
357
358/// Access an element of this map. Panics if the given key is not present in the
359/// map.
360impl<K, V, Q> ops::Index<&Q> for Map<K, V>
361where
362    K: Borrow<Q> + Ord,
363    Q: Ord + Eq + Hash + ?Sized,
364{
365    type Output = V;
366
367    fn index(&self, index: &Q) -> &V {
368        self.map.index(index)
369    }
370}
371
372/// Mutably access an element of this map. Panics if the given key is not
373/// present in the map.
374impl<K, V, Q> ops::IndexMut<&Q> for Map<K, V>
375where
376    K: Borrow<Q> + Ord,
377    Q: Ord + Eq + Hash + ?Sized,
378{
379    fn index_mut(&mut self, index: &Q) -> &mut V {
380        self.map.get_mut(index).expect("no entry found for key")
381    }
382}
383
384impl<K: Debug, V: Debug> Debug for Map<K, V> {
385    #[inline]
386    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
387        self.map.fmt(formatter)
388    }
389}
390
391impl<K: Ord + Hash, V> FromIterator<(K, V)> for Map<K, V> {
392    fn from_iter<T>(iter: T) -> Self
393    where
394        T: IntoIterator<Item = (K, V)>,
395    {
396        Self {
397            map: FromIterator::from_iter(iter),
398            dotted: false,
399            implicit: false,
400            inline: false,
401        }
402    }
403}
404
405impl<K: Ord + Hash, V> Extend<(K, V)> for Map<K, V> {
406    fn extend<T>(&mut self, iter: T)
407    where
408        T: IntoIterator<Item = (K, V)>,
409    {
410        self.map.extend(iter);
411    }
412}
413
414macro_rules! delegate_iterator {
415    (($name:ident $($generics:tt)*) => $item:ty) => {
416        impl $($generics)* Iterator for $name $($generics)* {
417            type Item = $item;
418            #[inline]
419            fn next(&mut self) -> Option<Self::Item> {
420                self.iter.next()
421            }
422            #[inline]
423            fn size_hint(&self) -> (usize, Option<usize>) {
424                self.iter.size_hint()
425            }
426        }
427
428        impl $($generics)* DoubleEndedIterator for $name $($generics)* {
429            #[inline]
430            fn next_back(&mut self) -> Option<Self::Item> {
431                self.iter.next_back()
432            }
433        }
434
435        impl $($generics)* ExactSizeIterator for $name $($generics)* {
436            #[inline]
437            fn len(&self) -> usize {
438                self.iter.len()
439            }
440        }
441    }
442}
443
444//////////////////////////////////////////////////////////////////////////////
445
446/// A view into a single entry in a map, which may either be vacant or occupied.
447/// This enum is constructed from the [`entry`] method on [`Map`].
448///
449/// [`entry`]: struct.Map.html#method.entry
450/// [`Map`]: struct.Map.html
451pub enum Entry<'a, K, V> {
452    /// A vacant Entry.
453    Vacant(VacantEntry<'a, K, V>),
454    /// An occupied Entry.
455    Occupied(OccupiedEntry<'a, K, V>),
456}
457
458/// A vacant Entry. It is part of the [`Entry`] enum.
459///
460/// [`Entry`]: enum.Entry.html
461pub struct VacantEntry<'a, K, V> {
462    vacant: VacantEntryImpl<'a, K, V>,
463}
464
465/// An occupied Entry. It is part of the [`Entry`] enum.
466///
467/// [`Entry`]: enum.Entry.html
468pub struct OccupiedEntry<'a, K, V> {
469    occupied: OccupiedEntryImpl<'a, K, V>,
470}
471
472#[cfg(not(feature = "preserve_order"))]
473type VacantEntryImpl<'a, K, V> = btree_map::VacantEntry<'a, K, V>;
474#[cfg(feature = "preserve_order")]
475type VacantEntryImpl<'a, K, V> = indexmap::map::VacantEntry<'a, K, V>;
476
477#[cfg(not(feature = "preserve_order"))]
478type OccupiedEntryImpl<'a, K, V> = btree_map::OccupiedEntry<'a, K, V>;
479#[cfg(feature = "preserve_order")]
480type OccupiedEntryImpl<'a, K, V> = indexmap::map::OccupiedEntry<'a, K, V>;
481
482impl<'a, K: Ord, V> Entry<'a, K, V> {
483    /// Returns a reference to this entry's key.
484    pub fn key(&self) -> &K {
485        match *self {
486            Entry::Vacant(ref e) => e.key(),
487            Entry::Occupied(ref e) => e.key(),
488        }
489    }
490
491    /// Ensures a value is in the entry by inserting the default if empty, and
492    /// returns a mutable reference to the value in the entry.
493    pub fn or_insert(self, default: V) -> &'a mut V {
494        match self {
495            Entry::Vacant(entry) => entry.insert(default),
496            Entry::Occupied(entry) => entry.into_mut(),
497        }
498    }
499
500    /// Ensures a value is in the entry by inserting the result of the default
501    /// function if empty, and returns a mutable reference to the value in the
502    /// entry.
503    pub fn or_insert_with<F>(self, default: F) -> &'a mut V
504    where
505        F: FnOnce() -> V,
506    {
507        match self {
508            Entry::Vacant(entry) => entry.insert(default()),
509            Entry::Occupied(entry) => entry.into_mut(),
510        }
511    }
512}
513
514impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
515    /// Gets a reference to the key that would be used when inserting a value
516    /// through the `VacantEntry`.
517    #[inline]
518    pub fn key(&self) -> &K {
519        self.vacant.key()
520    }
521
522    /// Sets the value of the entry with the `VacantEntry`'s key, and returns a
523    /// mutable reference to it.
524    #[inline]
525    pub fn insert(self, value: V) -> &'a mut V {
526        self.vacant.insert(value)
527    }
528}
529
530impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
531    /// Gets a reference to the key in the entry.
532    #[inline]
533    pub fn key(&self) -> &K {
534        self.occupied.key()
535    }
536
537    /// Gets a reference to the value in the entry.
538    #[inline]
539    pub fn get(&self) -> &V {
540        self.occupied.get()
541    }
542
543    /// Gets a mutable reference to the value in the entry.
544    #[inline]
545    pub fn get_mut(&mut self) -> &mut V {
546        self.occupied.get_mut()
547    }
548
549    /// Converts the entry into a mutable reference to its value.
550    #[inline]
551    pub fn into_mut(self) -> &'a mut V {
552        self.occupied.into_mut()
553    }
554
555    /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns
556    /// the entry's old value.
557    #[inline]
558    pub fn insert(&mut self, value: V) -> V {
559        self.occupied.insert(value)
560    }
561
562    /// Takes the value of the entry out of the map, and returns it.
563    #[inline]
564    pub fn remove(self) -> V {
565        #[cfg(not(feature = "preserve_order"))]
566        {
567            self.occupied.remove()
568        }
569        #[cfg(feature = "preserve_order")]
570        {
571            self.occupied.shift_remove()
572        }
573    }
574}
575
576//////////////////////////////////////////////////////////////////////////////
577
578impl<'a, K, V> IntoIterator for &'a Map<K, V> {
579    type Item = (&'a K, &'a V);
580    type IntoIter = Iter<'a, K, V>;
581    #[inline]
582    fn into_iter(self) -> Self::IntoIter {
583        Iter {
584            iter: self.map.iter(),
585        }
586    }
587}
588
589/// An iterator over a `toml::Map`'s entries.
590pub struct Iter<'a, K, V> {
591    iter: IterImpl<'a, K, V>,
592}
593
594#[cfg(not(feature = "preserve_order"))]
595type IterImpl<'a, K, V> = btree_map::Iter<'a, K, V>;
596#[cfg(feature = "preserve_order")]
597type IterImpl<'a, K, V> = indexmap::map::Iter<'a, K, V>;
598
599delegate_iterator!((Iter<'a, K, V>) => (&'a K, &'a V));
600
601//////////////////////////////////////////////////////////////////////////////
602
603impl<'a, K, V> IntoIterator for &'a mut Map<K, V> {
604    type Item = (&'a K, &'a mut V);
605    type IntoIter = IterMut<'a, K, V>;
606    #[inline]
607    fn into_iter(self) -> Self::IntoIter {
608        IterMut {
609            iter: self.map.iter_mut(),
610        }
611    }
612}
613
614/// A mutable iterator over a `toml::Map`'s entries.
615pub struct IterMut<'a, K, V> {
616    iter: IterMutImpl<'a, K, V>,
617}
618
619#[cfg(not(feature = "preserve_order"))]
620type IterMutImpl<'a, K, V> = btree_map::IterMut<'a, K, V>;
621#[cfg(feature = "preserve_order")]
622type IterMutImpl<'a, K, V> = indexmap::map::IterMut<'a, K, V>;
623
624delegate_iterator!((IterMut<'a, K, V>) => (&'a K, &'a mut V));
625
626//////////////////////////////////////////////////////////////////////////////
627
628impl<K, V> IntoIterator for Map<K, V> {
629    type Item = (K, V);
630    type IntoIter = IntoIter<K, V>;
631    #[inline]
632    fn into_iter(self) -> Self::IntoIter {
633        IntoIter {
634            iter: self.map.into_iter(),
635        }
636    }
637}
638
639/// An owning iterator over a `toml::Map`'s entries.
640pub struct IntoIter<K, V> {
641    iter: IntoIterImpl<K, V>,
642}
643
644#[cfg(not(feature = "preserve_order"))]
645type IntoIterImpl<K, V> = btree_map::IntoIter<K, V>;
646#[cfg(feature = "preserve_order")]
647type IntoIterImpl<K, V> = indexmap::map::IntoIter<K, V>;
648
649delegate_iterator!((IntoIter<K,V>) => (K, V));
650
651//////////////////////////////////////////////////////////////////////////////
652
653/// An iterator over a `toml::Map`'s keys.
654pub struct Keys<'a, K, V> {
655    iter: KeysImpl<'a, K, V>,
656}
657
658#[cfg(not(feature = "preserve_order"))]
659type KeysImpl<'a, K, V> = btree_map::Keys<'a, K, V>;
660#[cfg(feature = "preserve_order")]
661type KeysImpl<'a, K, V> = indexmap::map::Keys<'a, K, V>;
662
663delegate_iterator!((Keys<'a, K, V>) => &'a K);
664
665//////////////////////////////////////////////////////////////////////////////
666
667/// An iterator over a `toml::Map`'s values.
668pub struct Values<'a, K, V> {
669    iter: ValuesImpl<'a, K, V>,
670}
671
672#[cfg(not(feature = "preserve_order"))]
673type ValuesImpl<'a, K, V> = btree_map::Values<'a, K, V>;
674#[cfg(feature = "preserve_order")]
675type ValuesImpl<'a, K, V> = indexmap::map::Values<'a, K, V>;
676
677delegate_iterator!((Values<'a, K, V>) => &'a V);