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 (_, kv) in self.items.iter_mut() {
53            kv.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, 'c>(
74        &'s self,
75        parent: &[&'s Key],
76        values: &'c mut Vec<(Vec<&'s Key>, &'s Value)>,
77    ) {
78        for value in self.items.values() {
79            let mut path = parent.to_vec();
80            path.push(&value.key);
81            match &value.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 kv in self.items.values_mut() {
113            match &mut kv.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 = |_: &InternalString,
138                            val1: &TableKeyValue,
139                            _: &InternalString,
140                            val2: &TableKeyValue|
141         -> std::cmp::Ordering {
142            compare(&val1.key, &val1.value, &val2.key, &val2.value)
143        };
144
145        self.items.sort_by(modified_cmp);
146
147        for kv in self.items.values_mut() {
148            match &mut kv.value {
149                Item::Table(table) if table.is_dotted() => {
150                    table.sort_values_by_internal(compare);
151                }
152                _ => {}
153            }
154        }
155    }
156
157    /// If a table has no key/value pairs and implicit, it will not be displayed.
158    ///
159    /// # Examples
160    ///
161    /// ```notrust
162    /// [target."x86_64/windows.json".dependencies]
163    /// ```
164    ///
165    /// In the document above, tables `target` and `target."x86_64/windows.json"` are implicit.
166    ///
167    /// ```
168    /// use toml_edit::Document;
169    /// let mut doc = "[a]\n[a.b]\n".parse::<Document>().expect("invalid toml");
170    ///
171    /// doc["a"].as_table_mut().unwrap().set_implicit(true);
172    /// assert_eq!(doc.to_string(), "[a.b]\n");
173    /// ```
174    pub fn set_implicit(&mut self, implicit: bool) {
175        self.implicit = implicit;
176    }
177
178    /// If a table has no key/value pairs and implicit, it will not be displayed.
179    pub fn is_implicit(&self) -> bool {
180        self.implicit
181    }
182
183    /// Change this table's dotted status
184    pub fn set_dotted(&mut self, yes: bool) {
185        self.dotted = yes;
186    }
187
188    /// Check if this is a wrapper for dotted keys, rather than a standard table
189    pub fn is_dotted(&self) -> bool {
190        self.dotted
191    }
192
193    /// Sets the position of the `Table` within the `Document`.
194    pub fn set_position(&mut self, doc_position: usize) {
195        self.doc_position = Some(doc_position);
196    }
197
198    /// The position of the `Table` within the `Document`.
199    ///
200    /// Returns `None` if the `Table` was created manually (i.e. not via parsing)
201    /// in which case its position is set automatically.  This can be overridden with
202    /// [`Table::set_position`].
203    pub fn position(&self) -> Option<usize> {
204        self.doc_position
205    }
206
207    /// Returns the surrounding whitespace
208    pub fn decor_mut(&mut self) -> &mut Decor {
209        &mut self.decor
210    }
211
212    /// Returns the decor associated with a given key of the table.
213    pub fn decor(&self) -> &Decor {
214        &self.decor
215    }
216
217    /// Returns the decor associated with a given key of the table.
218    pub fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
219        self.items.get_mut(key).map(|kv| &mut kv.key.decor)
220    }
221
222    /// Returns the decor associated with a given key of the table.
223    pub fn key_decor(&self, key: &str) -> Option<&Decor> {
224        self.items.get(key).map(|kv| &kv.key.decor)
225    }
226
227    /// Returns the location within the original document
228    pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> {
229        self.span.clone()
230    }
231
232    pub(crate) fn despan(&mut self, input: &str) {
233        self.span = None;
234        self.decor.despan(input);
235        for kv in self.items.values_mut() {
236            kv.key.despan(input);
237            kv.value.despan(input);
238        }
239    }
240}
241
242impl Table {
243    /// Returns an iterator over all key/value pairs, including empty.
244    pub fn iter(&self) -> Iter<'_> {
245        Box::new(
246            self.items
247                .iter()
248                .filter(|(_, kv)| !kv.value.is_none())
249                .map(|(key, kv)| (&key[..], &kv.value)),
250        )
251    }
252
253    /// Returns an mutable iterator over all key/value pairs, including empty.
254    pub fn iter_mut(&mut self) -> IterMut<'_> {
255        Box::new(
256            self.items
257                .iter_mut()
258                .filter(|(_, kv)| !kv.value.is_none())
259                .map(|(_, kv)| (kv.key.as_mut(), &mut kv.value)),
260        )
261    }
262
263    /// Returns the number of non-empty items in the table.
264    pub fn len(&self) -> usize {
265        self.items.iter().filter(|i| !(i.1).value.is_none()).count()
266    }
267
268    /// Returns true iff the table is empty.
269    pub fn is_empty(&self) -> bool {
270        self.len() == 0
271    }
272
273    /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
274    pub fn clear(&mut self) {
275        self.items.clear()
276    }
277
278    /// Gets the given key's corresponding entry in the Table for in-place manipulation.
279    pub fn entry<'a>(&'a mut self, key: &str) -> Entry<'a> {
280        // Accept a `&str` rather than an owned type to keep `InternalString`, well, internal
281        match self.items.entry(key.into()) {
282            indexmap::map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { entry }),
283            indexmap::map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { entry, key: None }),
284        }
285    }
286
287    /// Gets the given key's corresponding entry in the Table for in-place manipulation.
288    pub fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a> {
289        // Accept a `&Key` to be consistent with `entry`
290        match self.items.entry(key.get().into()) {
291            indexmap::map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { entry }),
292            indexmap::map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry {
293                entry,
294                key: Some(key.to_owned()),
295            }),
296        }
297    }
298
299    /// Returns an optional reference to an item given the key.
300    pub fn get<'a>(&'a self, key: &str) -> Option<&'a Item> {
301        self.items.get(key).and_then(|kv| {
302            if !kv.value.is_none() {
303                Some(&kv.value)
304            } else {
305                None
306            }
307        })
308    }
309
310    /// Returns an optional mutable reference to an item given the key.
311    pub fn get_mut<'a>(&'a mut self, key: &str) -> Option<&'a mut Item> {
312        self.items.get_mut(key).and_then(|kv| {
313            if !kv.value.is_none() {
314                Some(&mut kv.value)
315            } else {
316                None
317            }
318        })
319    }
320
321    /// Return references to the key-value pair stored for key, if it is present, else None.
322    pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
323        self.items.get(key).and_then(|kv| {
324            if !kv.value.is_none() {
325                Some((&kv.key, &kv.value))
326            } else {
327                None
328            }
329        })
330    }
331
332    /// Return mutable references to the key-value pair stored for key, if it is present, else None.
333    pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
334        self.items.get_mut(key).and_then(|kv| {
335            if !kv.value.is_none() {
336                Some((kv.key.as_mut(), &mut kv.value))
337            } else {
338                None
339            }
340        })
341    }
342
343    /// Returns true iff the table contains an item with the given key.
344    pub fn contains_key(&self, key: &str) -> bool {
345        if let Some(kv) = self.items.get(key) {
346            !kv.value.is_none()
347        } else {
348            false
349        }
350    }
351
352    /// Returns true iff the table contains a table with the given key.
353    pub fn contains_table(&self, key: &str) -> bool {
354        if let Some(kv) = self.items.get(key) {
355            kv.value.is_table()
356        } else {
357            false
358        }
359    }
360
361    /// Returns true iff the table contains a value with the given key.
362    pub fn contains_value(&self, key: &str) -> bool {
363        if let Some(kv) = self.items.get(key) {
364            kv.value.is_value()
365        } else {
366            false
367        }
368    }
369
370    /// Returns true iff the table contains an array of tables with the given key.
371    pub fn contains_array_of_tables(&self, key: &str) -> bool {
372        if let Some(kv) = self.items.get(key) {
373            kv.value.is_array_of_tables()
374        } else {
375            false
376        }
377    }
378
379    /// Inserts a key-value pair into the map.
380    pub fn insert(&mut self, key: &str, item: Item) -> Option<Item> {
381        let kv = TableKeyValue::new(Key::new(key), item);
382        self.items.insert(key.into(), kv).map(|kv| kv.value)
383    }
384
385    /// Inserts a key-value pair into the map.
386    pub fn insert_formatted(&mut self, key: &Key, item: Item) -> Option<Item> {
387        let kv = TableKeyValue::new(key.to_owned(), item);
388        self.items.insert(key.get().into(), kv).map(|kv| kv.value)
389    }
390
391    /// Removes an item given the key.
392    pub fn remove(&mut self, key: &str) -> Option<Item> {
393        self.items.shift_remove(key).map(|kv| kv.value)
394    }
395
396    /// Removes a key from the map, returning the stored key and value if the key was previously in the map.
397    pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Item)> {
398        self.items.shift_remove(key).map(|kv| (kv.key, kv.value))
399    }
400}
401
402impl std::fmt::Display for Table {
403    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
404        use crate::encode::Encode;
405        let children = self.get_values();
406        // print table body
407        for (key_path, value) in children {
408            key_path.as_slice().encode(f, None, DEFAULT_KEY_DECOR)?;
409            write!(f, "=")?;
410            value.encode(f, None, DEFAULT_VALUE_DECOR)?;
411            writeln!(f)?;
412        }
413        Ok(())
414    }
415}
416
417impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for Table {
418    fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
419        for (key, value) in iter {
420            let key = key.into();
421            let value = Item::Value(value.into());
422            let value = TableKeyValue::new(key, value);
423            self.items.insert(value.key.get().into(), value);
424        }
425    }
426}
427
428impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for Table {
429    fn from_iter<I>(iter: I) -> Self
430    where
431        I: IntoIterator<Item = (K, V)>,
432    {
433        let mut table = Table::new();
434        table.extend(iter);
435        table
436    }
437}
438
439impl IntoIterator for Table {
440    type Item = (InternalString, Item);
441    type IntoIter = IntoIter;
442
443    fn into_iter(self) -> Self::IntoIter {
444        Box::new(self.items.into_iter().map(|(k, kv)| (k, kv.value)))
445    }
446}
447
448impl<'s> IntoIterator for &'s Table {
449    type Item = (&'s str, &'s Item);
450    type IntoIter = Iter<'s>;
451
452    fn into_iter(self) -> Self::IntoIter {
453        self.iter()
454    }
455}
456
457pub(crate) type KeyValuePairs = IndexMap<InternalString, TableKeyValue>;
458
459fn decorate_table(table: &mut Table) {
460    for (key_decor, value) in table
461        .items
462        .iter_mut()
463        .filter(|&(_, ref kv)| kv.value.is_value())
464        .map(|(_, kv)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap()))
465    {
466        key_decor.clear();
467        value.decor_mut().clear();
468    }
469}
470
471// `key1 = value1`
472pub(crate) const DEFAULT_KEY_DECOR: (&str, &str) = ("", " ");
473pub(crate) const DEFAULT_TABLE_DECOR: (&str, &str) = ("\n", "");
474pub(crate) const DEFAULT_KEY_PATH_DECOR: (&str, &str) = ("", "");
475
476#[derive(Debug, Clone)]
477pub(crate) struct TableKeyValue {
478    pub(crate) key: Key,
479    pub(crate) value: Item,
480}
481
482impl TableKeyValue {
483    pub(crate) fn new(key: Key, value: Item) -> Self {
484        TableKeyValue { key, value }
485    }
486}
487
488/// An owned iterator type over `Table`'s key/value pairs.
489pub type IntoIter = Box<dyn Iterator<Item = (InternalString, Item)>>;
490/// An iterator type over `Table`'s key/value pairs.
491pub type Iter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Item)> + 'a>;
492/// A mutable iterator type over `Table`'s key/value pairs.
493pub type IterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Item)> + 'a>;
494
495/// This trait represents either a `Table`, or an `InlineTable`.
496pub trait TableLike: crate::private::Sealed {
497    /// Returns an iterator over key/value pairs.
498    fn iter(&self) -> Iter<'_>;
499    /// Returns an mutable iterator over all key/value pairs, including empty.
500    fn iter_mut(&mut self) -> IterMut<'_>;
501    /// Returns the number of nonempty items.
502    fn len(&self) -> usize {
503        self.iter().filter(|&(_, v)| !v.is_none()).count()
504    }
505    /// Returns true iff the table is empty.
506    fn is_empty(&self) -> bool {
507        self.len() == 0
508    }
509    /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
510    fn clear(&mut self);
511    /// Gets the given key's corresponding entry in the Table for in-place manipulation.
512    fn entry<'a>(&'a mut self, key: &str) -> Entry<'a>;
513    /// Gets the given key's corresponding entry in the Table for in-place manipulation.
514    fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a>;
515    /// Returns an optional reference to an item given the key.
516    fn get<'s>(&'s self, key: &str) -> Option<&'s Item>;
517    /// Returns an optional mutable reference to an item given the key.
518    fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item>;
519    /// Return references to the key-value pair stored for key, if it is present, else None.
520    fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)>;
521    /// Return mutable references to the key-value pair stored for key, if it is present, else None.
522    fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)>;
523    /// Returns true iff the table contains an item with the given key.
524    fn contains_key(&self, key: &str) -> bool;
525    /// Inserts a key-value pair into the map.
526    fn insert(&mut self, key: &str, value: Item) -> Option<Item>;
527    /// Removes an item given the key.
528    fn remove(&mut self, key: &str) -> Option<Item>;
529
530    /// Get key/values for values that are visually children of this table
531    ///
532    /// For example, this will return dotted keys
533    fn get_values(&self) -> Vec<(Vec<&Key>, &Value)>;
534
535    /// Auto formats the table.
536    fn fmt(&mut self);
537    /// Sorts Key/Value Pairs of the table.
538    ///
539    /// Doesn't affect subtables or subarrays.
540    fn sort_values(&mut self);
541    /// Change this table's dotted status
542    fn set_dotted(&mut self, yes: bool);
543    /// Check if this is a wrapper for dotted keys, rather than a standard table
544    fn is_dotted(&self) -> bool;
545
546    /// Returns the decor associated with a given key of the table.
547    fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor>;
548    /// Returns the decor associated with a given key of the table.
549    fn key_decor(&self, key: &str) -> Option<&Decor>;
550}
551
552impl TableLike for Table {
553    fn iter(&self) -> Iter<'_> {
554        self.iter()
555    }
556    fn iter_mut(&mut self) -> IterMut<'_> {
557        self.iter_mut()
558    }
559    fn clear(&mut self) {
560        self.clear();
561    }
562    fn entry<'a>(&'a mut self, key: &str) -> Entry<'a> {
563        self.entry(key)
564    }
565    fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a> {
566        self.entry_format(key)
567    }
568    fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
569        self.get(key)
570    }
571    fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
572        self.get_mut(key)
573    }
574    fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
575        self.get_key_value(key)
576    }
577    fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
578        self.get_key_value_mut(key)
579    }
580    fn contains_key(&self, key: &str) -> bool {
581        self.contains_key(key)
582    }
583    fn insert(&mut self, key: &str, value: Item) -> Option<Item> {
584        self.insert(key, value)
585    }
586    fn remove(&mut self, key: &str) -> Option<Item> {
587        self.remove(key)
588    }
589
590    fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
591        self.get_values()
592    }
593    fn fmt(&mut self) {
594        self.fmt()
595    }
596    fn sort_values(&mut self) {
597        self.sort_values()
598    }
599    fn is_dotted(&self) -> bool {
600        self.is_dotted()
601    }
602    fn set_dotted(&mut self, yes: bool) {
603        self.set_dotted(yes)
604    }
605
606    fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
607        self.key_decor_mut(key)
608    }
609    fn key_decor(&self, key: &str) -> Option<&Decor> {
610        self.key_decor(key)
611    }
612}
613
614/// A view into a single location in a map, which may be vacant or occupied.
615pub enum Entry<'a> {
616    /// An occupied Entry.
617    Occupied(OccupiedEntry<'a>),
618    /// A vacant Entry.
619    Vacant(VacantEntry<'a>),
620}
621
622impl<'a> Entry<'a> {
623    /// Returns the entry key
624    ///
625    /// # Examples
626    ///
627    /// ```
628    /// use toml_edit::Table;
629    ///
630    /// let mut map = Table::new();
631    ///
632    /// assert_eq!("hello", map.entry("hello").key());
633    /// ```
634    pub fn key(&self) -> &str {
635        match self {
636            Entry::Occupied(e) => e.key(),
637            Entry::Vacant(e) => e.key(),
638        }
639    }
640
641    /// Ensures a value is in the entry by inserting the default if empty, and returns
642    /// a mutable reference to the value in the entry.
643    pub fn or_insert(self, default: Item) -> &'a mut Item {
644        match self {
645            Entry::Occupied(entry) => entry.into_mut(),
646            Entry::Vacant(entry) => entry.insert(default),
647        }
648    }
649
650    /// Ensures a value is in the entry by inserting the result of the default function if empty,
651    /// and returns a mutable reference to the value in the entry.
652    pub fn or_insert_with<F: FnOnce() -> Item>(self, default: F) -> &'a mut Item {
653        match self {
654            Entry::Occupied(entry) => entry.into_mut(),
655            Entry::Vacant(entry) => entry.insert(default()),
656        }
657    }
658}
659
660/// A view into a single occupied location in a `IndexMap`.
661pub struct OccupiedEntry<'a> {
662    pub(crate) entry: indexmap::map::OccupiedEntry<'a, InternalString, TableKeyValue>,
663}
664
665impl<'a> OccupiedEntry<'a> {
666    /// Gets a reference to the entry key
667    ///
668    /// # Examples
669    ///
670    /// ```
671    /// use toml_edit::Table;
672    ///
673    /// let mut map = Table::new();
674    ///
675    /// assert_eq!("foo", map.entry("foo").key());
676    /// ```
677    pub fn key(&self) -> &str {
678        self.entry.key().as_str()
679    }
680
681    /// Gets a mutable reference to the entry key
682    pub fn key_mut(&mut self) -> KeyMut<'_> {
683        self.entry.get_mut().key.as_mut()
684    }
685
686    /// Gets a reference to the value in the entry.
687    pub fn get(&self) -> &Item {
688        &self.entry.get().value
689    }
690
691    /// Gets a mutable reference to the value in the entry.
692    pub fn get_mut(&mut self) -> &mut Item {
693        &mut self.entry.get_mut().value
694    }
695
696    /// Converts the OccupiedEntry into a mutable reference to the value in the entry
697    /// with a lifetime bound to the map itself
698    pub fn into_mut(self) -> &'a mut Item {
699        &mut self.entry.into_mut().value
700    }
701
702    /// Sets the value of the entry, and returns the entry's old value
703    pub fn insert(&mut self, mut value: Item) -> Item {
704        std::mem::swap(&mut value, &mut self.entry.get_mut().value);
705        value
706    }
707
708    /// Takes the value out of the entry, and returns it
709    pub fn remove(self) -> Item {
710        self.entry.shift_remove().value
711    }
712}
713
714/// A view into a single empty location in a `IndexMap`.
715pub struct VacantEntry<'a> {
716    pub(crate) entry: indexmap::map::VacantEntry<'a, InternalString, TableKeyValue>,
717    pub(crate) key: Option<Key>,
718}
719
720impl<'a> VacantEntry<'a> {
721    /// Gets a reference to the entry key
722    ///
723    /// # Examples
724    ///
725    /// ```
726    /// use toml_edit::Table;
727    ///
728    /// let mut map = Table::new();
729    ///
730    /// assert_eq!("foo", map.entry("foo").key());
731    /// ```
732    pub fn key(&self) -> &str {
733        self.entry.key().as_str()
734    }
735
736    /// Sets the value of the entry with the VacantEntry's key,
737    /// and returns a mutable reference to it
738    pub fn insert(self, value: Item) -> &'a mut Item {
739        let entry = self.entry;
740        let key = self.key.unwrap_or_else(|| Key::new(entry.key().as_str()));
741        &mut entry.insert(TableKeyValue::new(key, value)).value
742    }
743}