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