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