Skip to main content

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