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