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