Skip to main content

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