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