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