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
362            .get(key)
363            .and_then(|value| if !value.is_none() { Some(value) } else { None })
364    }
365
366    /// Returns an optional mutable reference to an item given the key.
367    pub fn get_mut<'a>(&'a mut self, key: &str) -> Option<&'a mut Item> {
368        self.items
369            .get_mut(key)
370            .and_then(|value| if !value.is_none() { Some(value) } else { None })
371    }
372
373    /// Return references to the key-value pair stored for key, if it is present, else None.
374    pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
375        self.items.get_full(key).and_then(|(_, key, value)| {
376            if !value.is_none() {
377                Some((key, value))
378            } else {
379                None
380            }
381        })
382    }
383
384    /// Return mutable references to the key-value pair stored for key, if it is present, else None.
385    pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
386        use indexmap::map::MutableKeys;
387        self.items.get_full_mut2(key).and_then(|(_, key, value)| {
388            if !value.is_none() {
389                Some((key.as_mut(), value))
390            } else {
391                None
392            }
393        })
394    }
395
396    /// Returns true if the table contains an item with the given key.
397    pub fn contains_key(&self, key: &str) -> bool {
398        if let Some(value) = self.items.get(key) {
399            !value.is_none()
400        } else {
401            false
402        }
403    }
404
405    /// Returns true if the table contains a table with the given key.
406    pub fn contains_table(&self, key: &str) -> bool {
407        if let Some(value) = self.items.get(key) {
408            value.is_table()
409        } else {
410            false
411        }
412    }
413
414    /// Returns true if the table contains a value with the given key.
415    pub fn contains_value(&self, key: &str) -> bool {
416        if let Some(value) = self.items.get(key) {
417            value.is_value()
418        } else {
419            false
420        }
421    }
422
423    /// Returns true if the table contains an array of tables with the given key.
424    pub fn contains_array_of_tables(&self, key: &str) -> bool {
425        if let Some(value) = self.items.get(key) {
426            value.is_array_of_tables()
427        } else {
428            false
429        }
430    }
431
432    /// Inserts a key-value pair into the map.
433    pub fn insert(&mut self, key: &str, item: Item) -> Option<Item> {
434        use indexmap::map::MutableEntryKey;
435        let key = Key::new(key);
436        match self.items.entry(key.clone()) {
437            indexmap::map::Entry::Occupied(mut entry) => {
438                entry.key_mut().fmt();
439                let old = std::mem::replace(entry.get_mut(), item);
440                Some(old)
441            }
442            indexmap::map::Entry::Vacant(entry) => {
443                entry.insert(item);
444                None
445            }
446        }
447    }
448
449    /// Inserts a key-value pair into the map.
450    pub fn insert_formatted(&mut self, key: &Key, item: Item) -> Option<Item> {
451        use indexmap::map::MutableEntryKey;
452        match self.items.entry(key.clone()) {
453            indexmap::map::Entry::Occupied(mut entry) => {
454                *entry.key_mut() = key.clone();
455                let old = std::mem::replace(entry.get_mut(), item);
456                Some(old)
457            }
458            indexmap::map::Entry::Vacant(entry) => {
459                entry.insert(item);
460                None
461            }
462        }
463    }
464
465    /// Removes an item given the key.
466    pub fn remove(&mut self, key: &str) -> Option<Item> {
467        self.items.shift_remove(key)
468    }
469
470    /// Removes a key from the map, returning the stored key and value if the key was previously in the map.
471    pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Item)> {
472        self.items.shift_remove_entry(key)
473    }
474
475    /// Retains only the elements specified by the `keep` predicate.
476    ///
477    /// In other words, remove all pairs `(key, item)` for which
478    /// `keep(&key, &mut item)` returns `false`.
479    ///
480    /// The elements are visited in iteration order.
481    pub fn retain<F>(&mut self, mut keep: F)
482    where
483        F: FnMut(&str, &mut Item) -> bool,
484    {
485        self.items.retain(|key, value| keep(key, value));
486    }
487}
488
489#[cfg(feature = "display")]
490impl std::fmt::Display for Table {
491    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
492        let children = self.get_values();
493        // print table body
494        for (key_path, value) in children {
495            crate::encode::encode_key_path_ref(&key_path, f, None, DEFAULT_KEY_DECOR)?;
496            write!(f, "=")?;
497            crate::encode::encode_value(value, f, None, DEFAULT_VALUE_DECOR)?;
498            writeln!(f)?;
499        }
500        Ok(())
501    }
502}
503
504impl<K: Into<Key>, V: Into<Item>> Extend<(K, V)> for Table {
505    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
506        for (key, value) in iter {
507            let key = key.into();
508            let value = value.into();
509            self.items.insert(key, value);
510        }
511    }
512}
513
514impl<K: Into<Key>, V: Into<Item>> FromIterator<(K, V)> for Table {
515    fn from_iter<I>(iter: I) -> Self
516    where
517        I: IntoIterator<Item = (K, V)>,
518    {
519        let mut table = Self::new();
520        table.extend(iter);
521        table
522    }
523}
524
525impl IntoIterator for Table {
526    type Item = (String, Item);
527    type IntoIter = IntoIter;
528
529    fn into_iter(self) -> Self::IntoIter {
530        Box::new(self.items.into_iter().map(|(k, value)| (k.into(), value)))
531    }
532}
533
534impl<'s> IntoIterator for &'s Table {
535    type Item = (&'s str, &'s Item);
536    type IntoIter = Iter<'s>;
537
538    fn into_iter(self) -> Self::IntoIter {
539        self.iter()
540    }
541}
542
543pub(crate) type KeyValuePairs = IndexMap<Key, Item>;
544
545fn decorate_table(table: &mut Table) {
546    use indexmap::map::MutableKeys;
547    for (mut key, value) in table
548        .items
549        .iter_mut2()
550        .filter(|(_, value)| value.is_value())
551        .map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap()))
552    {
553        key.leaf_decor_mut().clear();
554        key.dotted_decor_mut().clear();
555        value.decor_mut().clear();
556    }
557}
558
559// `key1 = value1`
560pub(crate) const DEFAULT_ROOT_DECOR: (&str, &str) = ("", "");
561pub(crate) const DEFAULT_KEY_DECOR: (&str, &str) = ("", " ");
562pub(crate) const DEFAULT_TABLE_DECOR: (&str, &str) = ("\n", "");
563pub(crate) const DEFAULT_KEY_PATH_DECOR: (&str, &str) = ("", "");
564
565/// An owned iterator type over [`Table`]'s [`Key`]/[`Item`] pairs
566pub type IntoIter = Box<dyn Iterator<Item = (String, Item)>>;
567/// An iterator type over [`Table`]'s [`Key`]/[`Item`] pairs
568pub type Iter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Item)> + 'a>;
569/// A mutable iterator type over [`Table`]'s [`Key`]/[`Item`] pairs
570pub type IterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Item)> + 'a>;
571
572/// This trait represents either a `Table`, or an `InlineTable`.
573pub trait TableLike: crate::private::Sealed {
574    /// Returns an iterator over key/value pairs.
575    fn iter(&self) -> Iter<'_>;
576    /// Returns an mutable iterator over all key/value pairs, including empty.
577    fn iter_mut(&mut self) -> IterMut<'_>;
578    /// Returns the number of nonempty items.
579    fn len(&self) -> usize {
580        self.iter().filter(|&(_, v)| !v.is_none()).count()
581    }
582    /// Returns true if the table is empty.
583    fn is_empty(&self) -> bool {
584        self.len() == 0
585    }
586    /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
587    fn clear(&mut self);
588    /// Gets the given key's corresponding entry in the Table for in-place manipulation.
589    fn entry<'a>(&'a mut self, key: &str) -> Entry<'a>;
590    /// Gets the given key's corresponding entry in the Table for in-place manipulation.
591    fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a>;
592    /// Returns an optional reference to an item given the key.
593    fn get<'s>(&'s self, key: &str) -> Option<&'s Item>;
594    /// Returns an optional mutable reference to an item given the key.
595    fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item>;
596    /// Return references to the key-value pair stored for key, if it is present, else None.
597    fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)>;
598    /// Return mutable references to the key-value pair stored for key, if it is present, else None.
599    fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)>;
600    /// Returns true if the table contains an item with the given key.
601    fn contains_key(&self, key: &str) -> bool;
602    /// Inserts a key-value pair into the map.
603    fn insert(&mut self, key: &str, value: Item) -> Option<Item>;
604    /// Removes an item given the key.
605    fn remove(&mut self, key: &str) -> Option<Item>;
606
607    /// Get key/values for values that are visually children of this table
608    ///
609    /// For example, this will return dotted keys
610    fn get_values(&self) -> Vec<(Vec<&Key>, &Value)>;
611
612    /// Auto formats the table.
613    fn fmt(&mut self);
614    /// Sorts [Key]/[Value]-pairs of the table
615    ///
616    /// <div class="warning">
617    ///
618    /// This sorts the syntactic table (everything under the `[header]`) and not the logical map of
619    /// key-value pairs.
620    /// This does not affect the order of [sub-tables][Table] or [sub-arrays][crate::ArrayOfTables].
621    /// This is not recursive.
622    ///
623    /// </div>
624    fn sort_values(&mut self);
625    /// Change this table's dotted status
626    fn set_dotted(&mut self, yes: bool);
627    /// Check if this is a wrapper for dotted keys, rather than a standard table
628    fn is_dotted(&self) -> bool;
629
630    /// Returns an accessor to a key's formatting
631    fn key(&self, key: &str) -> Option<&'_ Key>;
632    /// Returns an accessor to a key's formatting
633    fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>>;
634}
635
636impl TableLike for Table {
637    fn iter(&self) -> Iter<'_> {
638        self.iter()
639    }
640    fn iter_mut(&mut self) -> IterMut<'_> {
641        self.iter_mut()
642    }
643    fn clear(&mut self) {
644        self.clear();
645    }
646    fn entry<'a>(&'a mut self, key: &str) -> Entry<'a> {
647        self.entry(key)
648    }
649    fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a> {
650        self.entry_format(key)
651    }
652    fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
653        self.get(key)
654    }
655    fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
656        self.get_mut(key)
657    }
658    fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
659        self.get_key_value(key)
660    }
661    fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
662        self.get_key_value_mut(key)
663    }
664    fn contains_key(&self, key: &str) -> bool {
665        self.contains_key(key)
666    }
667    fn insert(&mut self, key: &str, value: Item) -> Option<Item> {
668        self.insert(key, value)
669    }
670    fn remove(&mut self, key: &str) -> Option<Item> {
671        self.remove(key)
672    }
673
674    fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
675        self.get_values()
676    }
677    fn fmt(&mut self) {
678        self.fmt();
679    }
680    fn sort_values(&mut self) {
681        self.sort_values();
682    }
683    fn is_dotted(&self) -> bool {
684        self.is_dotted()
685    }
686    fn set_dotted(&mut self, yes: bool) {
687        self.set_dotted(yes);
688    }
689
690    fn key(&self, key: &str) -> Option<&'_ Key> {
691        self.key(key)
692    }
693    fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
694        self.key_mut(key)
695    }
696}
697
698/// A view into a single location in a [`Table`], which may be vacant or occupied.
699pub enum Entry<'a> {
700    /// An occupied Entry.
701    Occupied(OccupiedEntry<'a>),
702    /// A vacant Entry.
703    Vacant(VacantEntry<'a>),
704}
705
706impl<'a> Entry<'a> {
707    /// Returns the entry key
708    ///
709    /// # Examples
710    ///
711    /// ```
712    /// use toml_edit::Table;
713    ///
714    /// let mut map = Table::new();
715    ///
716    /// assert_eq!("hello", map.entry("hello").key());
717    /// ```
718    pub fn key(&self) -> &str {
719        match self {
720            Entry::Occupied(e) => e.key(),
721            Entry::Vacant(e) => e.key(),
722        }
723    }
724
725    /// Ensures a value is in the entry by inserting the default if empty, and returns
726    /// a mutable reference to the value in the entry.
727    pub fn or_insert(self, default: Item) -> &'a mut Item {
728        match self {
729            Entry::Occupied(entry) => entry.into_mut(),
730            Entry::Vacant(entry) => entry.insert(default),
731        }
732    }
733
734    /// Ensures a value is in the entry by inserting the result of the default function if empty,
735    /// and returns a mutable reference to the value in the entry.
736    pub fn or_insert_with<F: FnOnce() -> Item>(self, default: F) -> &'a mut Item {
737        match self {
738            Entry::Occupied(entry) => entry.into_mut(),
739            Entry::Vacant(entry) => entry.insert(default()),
740        }
741    }
742}
743
744/// A view into a single occupied location in a [`Table`].
745pub struct OccupiedEntry<'a> {
746    pub(crate) entry: indexmap::map::OccupiedEntry<'a, Key, Item>,
747}
748
749impl<'a> OccupiedEntry<'a> {
750    /// Gets a reference to the entry key
751    ///
752    /// # Examples
753    ///
754    /// ```
755    /// use toml_edit::Table;
756    ///
757    /// let mut map = Table::new();
758    ///
759    /// assert_eq!("foo", map.entry("foo").key());
760    /// ```
761    pub fn key(&self) -> &str {
762        self.entry.key().get()
763    }
764
765    /// Gets a mutable reference to the entry key
766    pub fn key_mut(&mut self) -> KeyMut<'_> {
767        use indexmap::map::MutableEntryKey;
768        self.entry.key_mut().as_mut()
769    }
770
771    /// Gets a reference to the value in the entry.
772    pub fn get(&self) -> &Item {
773        self.entry.get()
774    }
775
776    /// Gets a mutable reference to the value in the entry.
777    pub fn get_mut(&mut self) -> &mut Item {
778        self.entry.get_mut()
779    }
780
781    /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
782    /// with a lifetime bound to the map itself
783    pub fn into_mut(self) -> &'a mut Item {
784        self.entry.into_mut()
785    }
786
787    /// Sets the value of the entry, and returns the entry's old value
788    pub fn insert(&mut self, value: Item) -> Item {
789        self.entry.insert(value)
790    }
791
792    /// Takes the value out of the entry, and returns it
793    pub fn remove(self) -> Item {
794        self.entry.shift_remove()
795    }
796}
797
798/// A view into a single empty location in a [`Table`].
799pub struct VacantEntry<'a> {
800    pub(crate) entry: indexmap::map::VacantEntry<'a, Key, Item>,
801}
802
803impl<'a> VacantEntry<'a> {
804    /// Gets a reference to the entry key
805    ///
806    /// # Examples
807    ///
808    /// ```
809    /// use toml_edit::Table;
810    ///
811    /// let mut map = Table::new();
812    ///
813    /// assert_eq!("foo", map.entry("foo").key());
814    /// ```
815    pub fn key(&self) -> &str {
816        self.entry.key().get()
817    }
818
819    /// Sets the value of the entry with the `VacantEntry`'s key,
820    /// and returns a mutable reference to it
821    pub fn insert(self, value: Item) -> &'a mut Item {
822        let entry = self.entry;
823        entry.insert(value)
824    }
825}