toml_edit/
table.rs

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