toml_edit/
table.rs

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