toml_edit/
table.rs

1use std::iter::FromIterator;
2
3use indexmap::map::IndexMap;
4
5use crate::key::Key;
6use crate::repr::Decor;
7use crate::value::DEFAULT_VALUE_DECOR;
8use crate::{InlineTable, InternalString, Item, KeyMut, Value};
9
10/// Type representing a TOML non-inline table
11#[derive(Clone, Debug, Default)]
12pub struct Table {
13    // Comments/spaces before and after the header
14    pub(crate) decor: Decor,
15    // Whether to hide an empty table
16    pub(crate) implicit: bool,
17    // Whether this is a proxy for dotted keys
18    pub(crate) dotted: bool,
19    // Used for putting tables back in their original order when serialising.
20    //
21    // `None` for user created tables (can be overridden with `set_position`)
22    doc_position: Option<usize>,
23    pub(crate) span: Option<std::ops::Range<usize>>,
24    pub(crate) items: KeyValuePairs,
25}
26
27/// Constructors
28///
29/// See also `FromIterator`
30impl Table {
31    /// Creates an empty table.
32    pub fn new() -> Self {
33        Default::default()
34    }
35
36    pub(crate) fn with_pos(doc_position: Option<usize>) -> Self {
37        Self {
38            doc_position,
39            ..Default::default()
40        }
41    }
42
43    pub(crate) fn with_pairs(items: KeyValuePairs) -> Self {
44        Self {
45            items,
46            ..Default::default()
47        }
48    }
49
50    /// Convert to an inline table
51    pub fn into_inline_table(mut self) -> InlineTable {
52        for (_, value) in self.items.iter_mut() {
53            value.make_value();
54        }
55        let mut t = InlineTable::with_pairs(self.items);
56        t.fmt();
57        t
58    }
59}
60
61/// Formatting
62impl Table {
63    /// Get key/values for values that are visually children of this table
64    ///
65    /// For example, this will return dotted keys
66    pub fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
67        let mut values = Vec::new();
68        let root = Vec::new();
69        self.append_values(&root, &mut values);
70        values
71    }
72
73    fn append_values<'s>(
74        &'s self,
75        parent: &[&'s Key],
76        values: &mut Vec<(Vec<&'s Key>, &'s Value)>,
77    ) {
78        for (key, value) in self.items.iter() {
79            let mut path = parent.to_vec();
80            path.push(key);
81            match value {
82                Item::Table(table) if table.is_dotted() => {
83                    table.append_values(&path, values);
84                }
85                Item::Value(value) => {
86                    if let Some(table) = value.as_inline_table() {
87                        if table.is_dotted() {
88                            table.append_values(&path, values);
89                        } else {
90                            values.push((path, value));
91                        }
92                    } else {
93                        values.push((path, value));
94                    }
95                }
96                _ => {}
97            }
98        }
99    }
100
101    /// Auto formats the table.
102    pub fn fmt(&mut self) {
103        decorate_table(self);
104    }
105
106    /// Sorts Key/Value Pairs of the table.
107    ///
108    /// Doesn't affect subtables or subarrays.
109    pub fn sort_values(&mut self) {
110        // Assuming standard tables have their doc_position set and this won't negatively impact them
111        self.items.sort_keys();
112        for value in self.items.values_mut() {
113            match value {
114                Item::Table(table) if table.is_dotted() => {
115                    table.sort_values();
116                }
117                _ => {}
118            }
119        }
120    }
121
122    /// Sort Key/Value Pairs of the table using the using the comparison function `compare`.
123    ///
124    /// The comparison function receives two key and value pairs to compare (you can sort by keys or
125    /// values or their combination as needed).
126    pub fn sort_values_by<F>(&mut self, mut compare: F)
127    where
128        F: FnMut(&Key, &Item, &Key, &Item) -> std::cmp::Ordering,
129    {
130        self.sort_values_by_internal(&mut compare);
131    }
132
133    fn sort_values_by_internal<F>(&mut self, compare: &mut F)
134    where
135        F: FnMut(&Key, &Item, &Key, &Item) -> std::cmp::Ordering,
136    {
137        let modified_cmp =
138            |key1: &Key, val1: &Item, key2: &Key, val2: &Item| -> std::cmp::Ordering {
139                compare(key1, val1, key2, val2)
140            };
141
142        self.items.sort_by(modified_cmp);
143
144        for value in self.items.values_mut() {
145            match value {
146                Item::Table(table) if table.is_dotted() => {
147                    table.sort_values_by_internal(compare);
148                }
149                _ => {}
150            }
151        }
152    }
153
154    /// If a table has no key/value pairs and implicit, it will not be displayed.
155    ///
156    /// # Examples
157    ///
158    /// ```notrust
159    /// [target."x86_64/windows.json".dependencies]
160    /// ```
161    ///
162    /// In the document above, tables `target` and `target."x86_64/windows.json"` are implicit.
163    ///
164    /// ```
165    /// # #[cfg(feature = "parse")] {
166    /// # #[cfg(feature = "display")] {
167    /// use toml_edit::DocumentMut;
168    /// let mut doc = "[a]\n[a.b]\n".parse::<DocumentMut>().expect("invalid toml");
169    ///
170    /// doc["a"].as_table_mut().unwrap().set_implicit(true);
171    /// assert_eq!(doc.to_string(), "[a.b]\n");
172    /// # }
173    /// # }
174    /// ```
175    pub fn set_implicit(&mut self, implicit: bool) {
176        self.implicit = implicit;
177    }
178
179    /// If a table has no key/value pairs and implicit, it will not be displayed.
180    pub fn is_implicit(&self) -> bool {
181        self.implicit
182    }
183
184    /// Change this table's dotted status
185    pub fn set_dotted(&mut self, yes: bool) {
186        self.dotted = yes;
187    }
188
189    /// Check if this is a wrapper for dotted keys, rather than a standard table
190    pub fn is_dotted(&self) -> bool {
191        self.dotted
192    }
193
194    /// Sets the position of the `Table` within the [`DocumentMut`][crate::DocumentMut].
195    pub fn set_position(&mut self, doc_position: usize) {
196        self.doc_position = Some(doc_position);
197    }
198
199    /// The position of the `Table` within the [`DocumentMut`][crate::DocumentMut].
200    ///
201    /// Returns `None` if the `Table` was created manually (i.e. not via parsing)
202    /// in which case its position is set automatically.  This can be overridden with
203    /// [`Table::set_position`].
204    pub fn position(&self) -> Option<usize> {
205        self.doc_position
206    }
207
208    /// Returns the surrounding whitespace
209    pub fn decor_mut(&mut self) -> &mut Decor {
210        &mut self.decor
211    }
212
213    /// Returns the decor associated with a given key of the table.
214    pub fn decor(&self) -> &Decor {
215        &self.decor
216    }
217
218    /// Returns an accessor to a key's formatting
219    pub fn key(&self, key: &str) -> Option<&'_ Key> {
220        self.items.get_full(key).map(|(_, key, _)| key)
221    }
222
223    /// Returns an accessor to a key's formatting
224    pub fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
225        use indexmap::map::MutableKeys;
226        self.items
227            .get_full_mut2(key)
228            .map(|(_, key, _)| key.as_mut())
229    }
230
231    /// Returns the decor associated with a given key of the table.
232    #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
233    pub fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
234        #![allow(deprecated)]
235        use indexmap::map::MutableKeys;
236        self.items
237            .get_full_mut2(key)
238            .map(|(_, key, _)| key.leaf_decor_mut())
239    }
240
241    /// Returns the decor associated with a given key of the table.
242    #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
243    pub fn key_decor(&self, key: &str) -> Option<&Decor> {
244        #![allow(deprecated)]
245        self.items.get_full(key).map(|(_, key, _)| key.leaf_decor())
246    }
247
248    /// The location within the original document
249    ///
250    /// This generally requires an [`ImDocument`][crate::ImDocument].
251    pub fn span(&self) -> Option<std::ops::Range<usize>> {
252        self.span.clone()
253    }
254
255    pub(crate) fn despan(&mut self, input: &str) {
256        use indexmap::map::MutableKeys;
257        self.span = None;
258        self.decor.despan(input);
259        for (key, value) in self.items.iter_mut2() {
260            key.despan(input);
261            value.despan(input);
262        }
263    }
264}
265
266impl Table {
267    /// Returns an iterator over all key/value pairs, including empty.
268    pub fn iter(&self) -> Iter<'_> {
269        Box::new(
270            self.items
271                .iter()
272                .filter(|(_, value)| !value.is_none())
273                .map(|(key, value)| (key.get(), value)),
274        )
275    }
276
277    /// Returns an mutable iterator over all key/value pairs, including empty.
278    pub fn iter_mut(&mut self) -> IterMut<'_> {
279        use indexmap::map::MutableKeys;
280        Box::new(
281            self.items
282                .iter_mut2()
283                .filter(|(_, value)| !value.is_none())
284                .map(|(key, value)| (key.as_mut(), value)),
285        )
286    }
287
288    /// Returns the number of non-empty items in the table.
289    pub fn len(&self) -> usize {
290        self.iter().count()
291    }
292
293    /// Returns true if the table is empty.
294    pub fn is_empty(&self) -> bool {
295        self.len() == 0
296    }
297
298    /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
299    pub fn clear(&mut self) {
300        self.items.clear();
301    }
302
303    /// Gets the given key's corresponding entry in the Table for in-place manipulation.
304    pub fn entry<'a>(&'a mut self, key: &str) -> Entry<'a> {
305        // Accept a `&str` rather than an owned type to keep `InternalString`, well, internal
306        match self.items.entry(key.into()) {
307            indexmap::map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { entry }),
308            indexmap::map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { entry }),
309        }
310    }
311
312    /// Gets the given key's corresponding entry in the Table for in-place manipulation.
313    pub fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a> {
314        // Accept a `&Key` to be consistent with `entry`
315        match self.items.entry(key.clone()) {
316            indexmap::map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { entry }),
317            indexmap::map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { entry }),
318        }
319    }
320
321    /// Returns an optional reference to an item given the key.
322    pub fn get<'a>(&'a self, key: &str) -> Option<&'a Item> {
323        self.items
324            .get(key)
325            .and_then(|value| if !value.is_none() { Some(value) } else { None })
326    }
327
328    /// Returns an optional mutable reference to an item given the key.
329    pub fn get_mut<'a>(&'a mut self, key: &str) -> Option<&'a mut Item> {
330        self.items
331            .get_mut(key)
332            .and_then(|value| if !value.is_none() { Some(value) } else { None })
333    }
334
335    /// Return references to the key-value pair stored for key, if it is present, else None.
336    pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
337        self.items.get_full(key).and_then(|(_, key, value)| {
338            if !value.is_none() {
339                Some((key, value))
340            } else {
341                None
342            }
343        })
344    }
345
346    /// Return mutable references to the key-value pair stored for key, if it is present, else None.
347    pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
348        use indexmap::map::MutableKeys;
349        self.items.get_full_mut2(key).and_then(|(_, key, value)| {
350            if !value.is_none() {
351                Some((key.as_mut(), value))
352            } else {
353                None
354            }
355        })
356    }
357
358    /// Returns true if the table contains an item with the given key.
359    pub fn contains_key(&self, key: &str) -> bool {
360        if let Some(value) = self.items.get(key) {
361            !value.is_none()
362        } else {
363            false
364        }
365    }
366
367    /// Returns true if the table contains a table with the given key.
368    pub fn contains_table(&self, key: &str) -> bool {
369        if let Some(value) = self.items.get(key) {
370            value.is_table()
371        } else {
372            false
373        }
374    }
375
376    /// Returns true if the table contains a value with the given key.
377    pub fn contains_value(&self, key: &str) -> bool {
378        if let Some(value) = self.items.get(key) {
379            value.is_value()
380        } else {
381            false
382        }
383    }
384
385    /// Returns true if the table contains an array of tables with the given key.
386    pub fn contains_array_of_tables(&self, key: &str) -> bool {
387        if let Some(value) = self.items.get(key) {
388            value.is_array_of_tables()
389        } else {
390            false
391        }
392    }
393
394    /// Inserts a key-value pair into the map.
395    pub fn insert(&mut self, key: &str, item: Item) -> Option<Item> {
396        use indexmap::map::MutableEntryKey;
397        let key = Key::new(key);
398        match self.items.entry(key.clone()) {
399            indexmap::map::Entry::Occupied(mut entry) => {
400                entry.key_mut().fmt();
401                let old = std::mem::replace(entry.get_mut(), item);
402                Some(old)
403            }
404            indexmap::map::Entry::Vacant(entry) => {
405                entry.insert(item);
406                None
407            }
408        }
409    }
410
411    /// Inserts a key-value pair into the map.
412    pub fn insert_formatted(&mut self, key: &Key, item: Item) -> Option<Item> {
413        use indexmap::map::MutableEntryKey;
414        match self.items.entry(key.clone()) {
415            indexmap::map::Entry::Occupied(mut entry) => {
416                *entry.key_mut() = key.clone();
417                let old = std::mem::replace(entry.get_mut(), item);
418                Some(old)
419            }
420            indexmap::map::Entry::Vacant(entry) => {
421                entry.insert(item);
422                None
423            }
424        }
425    }
426
427    /// Removes an item given the key.
428    pub fn remove(&mut self, key: &str) -> Option<Item> {
429        self.items.shift_remove(key)
430    }
431
432    /// Removes a key from the map, returning the stored key and value if the key was previously in the map.
433    pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Item)> {
434        self.items.shift_remove_entry(key)
435    }
436
437    /// Retains only the elements specified by the `keep` predicate.
438    ///
439    /// In other words, remove all pairs `(key, item)` for which
440    /// `keep(&key, &mut item)` returns `false`.
441    ///
442    /// The elements are visited in iteration order.
443    pub fn retain<F>(&mut self, mut keep: F)
444    where
445        F: FnMut(&str, &mut Item) -> bool,
446    {
447        self.items.retain(|key, value| keep(key, value));
448    }
449}
450
451#[cfg(feature = "display")]
452impl std::fmt::Display for Table {
453    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
454        let children = self.get_values();
455        // print table body
456        for (key_path, value) in children {
457            crate::encode::encode_key_path_ref(&key_path, f, None, DEFAULT_KEY_DECOR)?;
458            write!(f, "=")?;
459            crate::encode::encode_value(value, f, None, DEFAULT_VALUE_DECOR)?;
460            writeln!(f)?;
461        }
462        Ok(())
463    }
464}
465
466impl<K: Into<Key>, V: Into<Item>> Extend<(K, V)> for Table {
467    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
468        for (key, value) in iter {
469            let key = key.into();
470            let value = value.into();
471            self.items.insert(key, value);
472        }
473    }
474}
475
476impl<K: Into<Key>, V: Into<Item>> FromIterator<(K, V)> for Table {
477    fn from_iter<I>(iter: I) -> Self
478    where
479        I: IntoIterator<Item = (K, V)>,
480    {
481        let mut table = Table::new();
482        table.extend(iter);
483        table
484    }
485}
486
487impl IntoIterator for Table {
488    type Item = (InternalString, Item);
489    type IntoIter = IntoIter;
490
491    fn into_iter(self) -> Self::IntoIter {
492        Box::new(self.items.into_iter().map(|(k, value)| (k.into(), value)))
493    }
494}
495
496impl<'s> IntoIterator for &'s Table {
497    type Item = (&'s str, &'s Item);
498    type IntoIter = Iter<'s>;
499
500    fn into_iter(self) -> Self::IntoIter {
501        self.iter()
502    }
503}
504
505pub(crate) type KeyValuePairs = IndexMap<Key, Item>;
506
507fn decorate_table(table: &mut Table) {
508    use indexmap::map::MutableKeys;
509    for (mut key, value) in table
510        .items
511        .iter_mut2()
512        .filter(|(_, value)| value.is_value())
513        .map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap()))
514    {
515        key.leaf_decor_mut().clear();
516        key.dotted_decor_mut().clear();
517        value.decor_mut().clear();
518    }
519}
520
521// `key1 = value1`
522pub(crate) const DEFAULT_ROOT_DECOR: (&str, &str) = ("", "");
523pub(crate) const DEFAULT_KEY_DECOR: (&str, &str) = ("", " ");
524pub(crate) const DEFAULT_TABLE_DECOR: (&str, &str) = ("\n", "");
525pub(crate) const DEFAULT_KEY_PATH_DECOR: (&str, &str) = ("", "");
526
527/// An owned iterator type over `Table`'s key/value pairs.
528pub type IntoIter = Box<dyn Iterator<Item = (InternalString, Item)>>;
529/// An iterator type over `Table`'s key/value pairs.
530pub type Iter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Item)> + 'a>;
531/// A mutable iterator type over `Table`'s key/value pairs.
532pub type IterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Item)> + 'a>;
533
534/// This trait represents either a `Table`, or an `InlineTable`.
535pub trait TableLike: crate::private::Sealed {
536    /// Returns an iterator over key/value pairs.
537    fn iter(&self) -> Iter<'_>;
538    /// Returns an mutable iterator over all key/value pairs, including empty.
539    fn iter_mut(&mut self) -> IterMut<'_>;
540    /// Returns the number of nonempty items.
541    fn len(&self) -> usize {
542        self.iter().filter(|&(_, v)| !v.is_none()).count()
543    }
544    /// Returns true if the table is empty.
545    fn is_empty(&self) -> bool {
546        self.len() == 0
547    }
548    /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
549    fn clear(&mut self);
550    /// Gets the given key's corresponding entry in the Table for in-place manipulation.
551    fn entry<'a>(&'a mut self, key: &str) -> Entry<'a>;
552    /// Gets the given key's corresponding entry in the Table for in-place manipulation.
553    fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a>;
554    /// Returns an optional reference to an item given the key.
555    fn get<'s>(&'s self, key: &str) -> Option<&'s Item>;
556    /// Returns an optional mutable reference to an item given the key.
557    fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item>;
558    /// Return references to the key-value pair stored for key, if it is present, else None.
559    fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)>;
560    /// Return mutable references to the key-value pair stored for key, if it is present, else None.
561    fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)>;
562    /// Returns true if the table contains an item with the given key.
563    fn contains_key(&self, key: &str) -> bool;
564    /// Inserts a key-value pair into the map.
565    fn insert(&mut self, key: &str, value: Item) -> Option<Item>;
566    /// Removes an item given the key.
567    fn remove(&mut self, key: &str) -> Option<Item>;
568
569    /// Get key/values for values that are visually children of this table
570    ///
571    /// For example, this will return dotted keys
572    fn get_values(&self) -> Vec<(Vec<&Key>, &Value)>;
573
574    /// Auto formats the table.
575    fn fmt(&mut self);
576    /// Sorts Key/Value Pairs of the table.
577    ///
578    /// Doesn't affect subtables or subarrays.
579    fn sort_values(&mut self);
580    /// Change this table's dotted status
581    fn set_dotted(&mut self, yes: bool);
582    /// Check if this is a wrapper for dotted keys, rather than a standard table
583    fn is_dotted(&self) -> bool;
584
585    /// Returns an accessor to a key's formatting
586    fn key(&self, key: &str) -> Option<&'_ Key>;
587    /// Returns an accessor to a key's formatting
588    fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>>;
589    /// Returns the decor associated with a given key of the table.
590    #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
591    fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor>;
592    /// Returns the decor associated with a given key of the table.
593    #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
594    fn key_decor(&self, key: &str) -> Option<&Decor>;
595}
596
597impl TableLike for Table {
598    fn iter(&self) -> Iter<'_> {
599        self.iter()
600    }
601    fn iter_mut(&mut self) -> IterMut<'_> {
602        self.iter_mut()
603    }
604    fn clear(&mut self) {
605        self.clear();
606    }
607    fn entry<'a>(&'a mut self, key: &str) -> Entry<'a> {
608        self.entry(key)
609    }
610    fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a> {
611        self.entry_format(key)
612    }
613    fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
614        self.get(key)
615    }
616    fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
617        self.get_mut(key)
618    }
619    fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
620        self.get_key_value(key)
621    }
622    fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
623        self.get_key_value_mut(key)
624    }
625    fn contains_key(&self, key: &str) -> bool {
626        self.contains_key(key)
627    }
628    fn insert(&mut self, key: &str, value: Item) -> Option<Item> {
629        self.insert(key, value)
630    }
631    fn remove(&mut self, key: &str) -> Option<Item> {
632        self.remove(key)
633    }
634
635    fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
636        self.get_values()
637    }
638    fn fmt(&mut self) {
639        self.fmt();
640    }
641    fn sort_values(&mut self) {
642        self.sort_values();
643    }
644    fn is_dotted(&self) -> bool {
645        self.is_dotted()
646    }
647    fn set_dotted(&mut self, yes: bool) {
648        self.set_dotted(yes);
649    }
650
651    fn key(&self, key: &str) -> Option<&'_ Key> {
652        self.key(key)
653    }
654    fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
655        self.key_mut(key)
656    }
657    fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
658        #![allow(deprecated)]
659        self.key_decor_mut(key)
660    }
661    fn key_decor(&self, key: &str) -> Option<&Decor> {
662        #![allow(deprecated)]
663        self.key_decor(key)
664    }
665}
666
667/// A view into a single location in a map, which may be vacant or occupied.
668pub enum Entry<'a> {
669    /// An occupied Entry.
670    Occupied(OccupiedEntry<'a>),
671    /// A vacant Entry.
672    Vacant(VacantEntry<'a>),
673}
674
675impl<'a> Entry<'a> {
676    /// Returns the entry key
677    ///
678    /// # Examples
679    ///
680    /// ```
681    /// use toml_edit::Table;
682    ///
683    /// let mut map = Table::new();
684    ///
685    /// assert_eq!("hello", map.entry("hello").key());
686    /// ```
687    pub fn key(&self) -> &str {
688        match self {
689            Entry::Occupied(e) => e.key(),
690            Entry::Vacant(e) => e.key(),
691        }
692    }
693
694    /// Ensures a value is in the entry by inserting the default if empty, and returns
695    /// a mutable reference to the value in the entry.
696    pub fn or_insert(self, default: Item) -> &'a mut Item {
697        match self {
698            Entry::Occupied(entry) => entry.into_mut(),
699            Entry::Vacant(entry) => entry.insert(default),
700        }
701    }
702
703    /// Ensures a value is in the entry by inserting the result of the default function if empty,
704    /// and returns a mutable reference to the value in the entry.
705    pub fn or_insert_with<F: FnOnce() -> Item>(self, default: F) -> &'a mut Item {
706        match self {
707            Entry::Occupied(entry) => entry.into_mut(),
708            Entry::Vacant(entry) => entry.insert(default()),
709        }
710    }
711}
712
713/// A view into a single occupied location in a `IndexMap`.
714pub struct OccupiedEntry<'a> {
715    pub(crate) entry: indexmap::map::OccupiedEntry<'a, Key, Item>,
716}
717
718impl<'a> OccupiedEntry<'a> {
719    /// Gets a reference to the entry key
720    ///
721    /// # Examples
722    ///
723    /// ```
724    /// use toml_edit::Table;
725    ///
726    /// let mut map = Table::new();
727    ///
728    /// assert_eq!("foo", map.entry("foo").key());
729    /// ```
730    pub fn key(&self) -> &str {
731        self.entry.key().get()
732    }
733
734    /// Gets a mutable reference to the entry key
735    pub fn key_mut(&mut self) -> KeyMut<'_> {
736        use indexmap::map::MutableEntryKey;
737        self.entry.key_mut().as_mut()
738    }
739
740    /// Gets a reference to the value in the entry.
741    pub fn get(&self) -> &Item {
742        self.entry.get()
743    }
744
745    /// Gets a mutable reference to the value in the entry.
746    pub fn get_mut(&mut self) -> &mut Item {
747        self.entry.get_mut()
748    }
749
750    /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
751    /// with a lifetime bound to the map itself
752    pub fn into_mut(self) -> &'a mut Item {
753        self.entry.into_mut()
754    }
755
756    /// Sets the value of the entry, and returns the entry's old value
757    pub fn insert(&mut self, value: Item) -> Item {
758        self.entry.insert(value)
759    }
760
761    /// Takes the value out of the entry, and returns it
762    pub fn remove(self) -> Item {
763        self.entry.shift_remove()
764    }
765}
766
767/// A view into a single empty location in a `IndexMap`.
768pub struct VacantEntry<'a> {
769    pub(crate) entry: indexmap::map::VacantEntry<'a, Key, Item>,
770}
771
772impl<'a> VacantEntry<'a> {
773    /// Gets a reference to the entry key
774    ///
775    /// # Examples
776    ///
777    /// ```
778    /// use toml_edit::Table;
779    ///
780    /// let mut map = Table::new();
781    ///
782    /// assert_eq!("foo", map.entry("foo").key());
783    /// ```
784    pub fn key(&self) -> &str {
785        self.entry.key().get()
786    }
787
788    /// Sets the value of the entry with the `VacantEntry`'s key,
789    /// and returns a mutable reference to it
790    pub fn insert(self, value: Item) -> &'a mut Item {
791        let entry = self.entry;
792        entry.insert(value)
793    }
794}