toml_edit/
inline_table.rs

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