• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::DocumentMut;
152     /// let mut doc = "[a]\n[a.b]\n".parse::<DocumentMut>().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     /// The location within the original document
223     ///
224     /// This generally requires an [`ImDocument`][crate::ImDocument].
span(&self) -> Option<std::ops::Range<usize>>225     pub fn span(&self) -> Option<std::ops::Range<usize>> {
226         self.span.clone()
227     }
228 
despan(&mut self, input: &str)229     pub(crate) fn despan(&mut self, input: &str) {
230         self.span = None;
231         self.decor.despan(input);
232         self.preamble.despan(input);
233         for kv in self.items.values_mut() {
234             kv.key.despan(input);
235             kv.value.despan(input);
236         }
237     }
238 }
239 
240 impl InlineTable {
241     /// Returns an iterator over key/value pairs.
iter(&self) -> InlineTableIter<'_>242     pub fn iter(&self) -> InlineTableIter<'_> {
243         Box::new(
244             self.items
245                 .iter()
246                 .filter(|&(_, kv)| kv.value.is_value())
247                 .map(|(k, kv)| (&k[..], kv.value.as_value().unwrap())),
248         )
249     }
250 
251     /// Returns an iterator over key/value pairs.
iter_mut(&mut self) -> InlineTableIterMut<'_>252     pub fn iter_mut(&mut self) -> InlineTableIterMut<'_> {
253         Box::new(
254             self.items
255                 .iter_mut()
256                 .filter(|(_, kv)| kv.value.is_value())
257                 .map(|(_, kv)| (kv.key.as_mut(), kv.value.as_value_mut().unwrap())),
258         )
259     }
260 
261     /// Returns the number of key/value pairs.
len(&self) -> usize262     pub fn len(&self) -> usize {
263         self.iter().count()
264     }
265 
266     /// Returns true if the table is empty.
is_empty(&self) -> bool267     pub fn is_empty(&self) -> bool {
268         self.len() == 0
269     }
270 
271     /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
clear(&mut self)272     pub fn clear(&mut self) {
273         self.items.clear();
274     }
275 
276     /// Gets the given key's corresponding entry in the Table for in-place manipulation.
entry(&'_ mut self, key: impl Into<InternalString>) -> InlineEntry<'_>277     pub fn entry(&'_ mut self, key: impl Into<InternalString>) -> InlineEntry<'_> {
278         match self.items.entry(key.into()) {
279             indexmap::map::Entry::Occupied(mut entry) => {
280                 // Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code.
281                 let scratch = std::mem::take(&mut entry.get_mut().value);
282                 let scratch = Item::Value(
283                     scratch
284                         .into_value()
285                         // HACK: `Item::None` is a corner case of a corner case, let's just pick a
286                         // "safe" value
287                         .unwrap_or_else(|_| Value::InlineTable(Default::default())),
288                 );
289                 entry.get_mut().value = scratch;
290 
291                 InlineEntry::Occupied(InlineOccupiedEntry { entry })
292             }
293             indexmap::map::Entry::Vacant(entry) => {
294                 InlineEntry::Vacant(InlineVacantEntry { entry, key: None })
295             }
296         }
297     }
298 
299     /// Gets the given key's corresponding entry in the Table for in-place manipulation.
entry_format<'a>(&'a mut self, key: &Key) -> InlineEntry<'a>300     pub fn entry_format<'a>(&'a mut self, key: &Key) -> InlineEntry<'a> {
301         // Accept a `&Key` to be consistent with `entry`
302         match self.items.entry(key.get().into()) {
303             indexmap::map::Entry::Occupied(mut entry) => {
304                 // Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code.
305                 let scratch = std::mem::take(&mut entry.get_mut().value);
306                 let scratch = Item::Value(
307                     scratch
308                         .into_value()
309                         // HACK: `Item::None` is a corner case of a corner case, let's just pick a
310                         // "safe" value
311                         .unwrap_or_else(|_| Value::InlineTable(Default::default())),
312                 );
313                 entry.get_mut().value = scratch;
314 
315                 InlineEntry::Occupied(InlineOccupiedEntry { entry })
316             }
317             indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry {
318                 entry,
319                 key: Some(key.clone()),
320             }),
321         }
322     }
323     /// Return an optional reference to the value at the given the key.
get(&self, key: &str) -> Option<&Value>324     pub fn get(&self, key: &str) -> Option<&Value> {
325         self.items.get(key).and_then(|kv| kv.value.as_value())
326     }
327 
328     /// Return an optional mutable reference to the value at the given the key.
get_mut(&mut self, key: &str) -> Option<&mut Value>329     pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
330         self.items
331             .get_mut(key)
332             .and_then(|kv| kv.value.as_value_mut())
333     }
334 
335     /// 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)>336     pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
337         self.items.get(key).and_then(|kv| {
338             if !kv.value.is_none() {
339                 Some((&kv.key, &kv.value))
340             } else {
341                 None
342             }
343         })
344     }
345 
346     /// Return mutable references to the key-value pair stored for key, if it is present, else None.
get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)>347     pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
348         self.items.get_mut(key).and_then(|kv| {
349             if !kv.value.is_none() {
350                 Some((kv.key.as_mut(), &mut kv.value))
351             } else {
352                 None
353             }
354         })
355     }
356 
357     /// Returns true if the table contains given key.
contains_key(&self, key: &str) -> bool358     pub fn contains_key(&self, key: &str) -> bool {
359         if let Some(kv) = self.items.get(key) {
360             kv.value.is_value()
361         } else {
362             false
363         }
364     }
365 
366     /// Inserts a key/value pair if the table does not contain the key.
367     /// Returns a mutable reference to the corresponding value.
get_or_insert<V: Into<Value>>( &mut self, key: impl Into<InternalString>, value: V, ) -> &mut Value368     pub fn get_or_insert<V: Into<Value>>(
369         &mut self,
370         key: impl Into<InternalString>,
371         value: V,
372     ) -> &mut Value {
373         let key = key.into();
374         self.items
375             .entry(key.clone())
376             .or_insert(TableKeyValue::new(Key::new(key), Item::Value(value.into())))
377             .value
378             .as_value_mut()
379             .expect("non-value type in inline table")
380     }
381 
382     /// Inserts a key-value pair into the map.
insert(&mut self, key: impl Into<InternalString>, value: Value) -> Option<Value>383     pub fn insert(&mut self, key: impl Into<InternalString>, value: Value) -> Option<Value> {
384         let key = key.into();
385         let kv = TableKeyValue::new(Key::new(key.clone()), Item::Value(value));
386         self.items
387             .insert(key, kv)
388             .and_then(|kv| kv.value.into_value().ok())
389     }
390 
391     /// Inserts a key-value pair into the map.
insert_formatted(&mut self, key: &Key, value: Value) -> Option<Value>392     pub fn insert_formatted(&mut self, key: &Key, value: Value) -> Option<Value> {
393         let kv = TableKeyValue::new(key.to_owned(), Item::Value(value));
394         self.items
395             .insert(InternalString::from(key.get()), kv)
396             .filter(|kv| kv.value.is_value())
397             .map(|kv| kv.value.into_value().unwrap())
398     }
399 
400     /// Removes an item given the key.
remove(&mut self, key: &str) -> Option<Value>401     pub fn remove(&mut self, key: &str) -> Option<Value> {
402         self.items
403             .shift_remove(key)
404             .and_then(|kv| kv.value.into_value().ok())
405     }
406 
407     /// 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)>408     pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Value)> {
409         self.items.shift_remove(key).and_then(|kv| {
410             let key = kv.key;
411             kv.value.into_value().ok().map(|value| (key, value))
412         })
413     }
414 
415     /// Retains only the elements specified by the `keep` predicate.
416     ///
417     /// In other words, remove all pairs `(key, value)` for which
418     /// `keep(&key, &mut value)` returns `false`.
419     ///
420     /// The elements are visited in iteration order.
retain<F>(&mut self, mut keep: F) where F: FnMut(&str, &mut Value) -> bool,421     pub fn retain<F>(&mut self, mut keep: F)
422     where
423         F: FnMut(&str, &mut Value) -> bool,
424     {
425         self.items.retain(|key, item| {
426             item.value
427                 .as_value_mut()
428                 .map(|value| keep(key, value))
429                 .unwrap_or(false)
430         });
431     }
432 }
433 
434 #[cfg(feature = "display")]
435 impl std::fmt::Display for InlineTable {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result436     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
437         crate::encode::encode_table(self, f, None, ("", ""))
438     }
439 }
440 
441 impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for InlineTable {
extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T)442     fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
443         for (key, value) in iter {
444             let key = key.into();
445             let value = Item::Value(value.into());
446             let value = TableKeyValue::new(key, value);
447             self.items
448                 .insert(InternalString::from(value.key.get()), value);
449         }
450     }
451 }
452 
453 impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for InlineTable {
from_iter<I>(iter: I) -> Self where I: IntoIterator<Item = (K, V)>,454     fn from_iter<I>(iter: I) -> Self
455     where
456         I: IntoIterator<Item = (K, V)>,
457     {
458         let mut table = InlineTable::new();
459         table.extend(iter);
460         table
461     }
462 }
463 
464 impl IntoIterator for InlineTable {
465     type Item = (InternalString, Value);
466     type IntoIter = InlineTableIntoIter;
467 
into_iter(self) -> Self::IntoIter468     fn into_iter(self) -> Self::IntoIter {
469         Box::new(
470             self.items
471                 .into_iter()
472                 .filter(|(_, kv)| kv.value.is_value())
473                 .map(|(k, kv)| (k, kv.value.into_value().unwrap())),
474         )
475     }
476 }
477 
478 impl<'s> IntoIterator for &'s InlineTable {
479     type Item = (&'s str, &'s Value);
480     type IntoIter = InlineTableIter<'s>;
481 
into_iter(self) -> Self::IntoIter482     fn into_iter(self) -> Self::IntoIter {
483         self.iter()
484     }
485 }
486 
decorate_inline_table(table: &mut InlineTable)487 fn decorate_inline_table(table: &mut InlineTable) {
488     for (mut key, value) in table
489         .items
490         .iter_mut()
491         .filter(|(_, kv)| kv.value.is_value())
492         .map(|(_, kv)| (kv.key.as_mut(), kv.value.as_value_mut().unwrap()))
493     {
494         key.leaf_decor_mut().clear();
495         key.dotted_decor_mut().clear();
496         value.decor_mut().clear();
497     }
498 }
499 
500 /// An owned iterator type over key/value pairs of an inline table.
501 pub type InlineTableIntoIter = Box<dyn Iterator<Item = (InternalString, Value)>>;
502 /// An iterator type over key/value pairs of an inline table.
503 pub type InlineTableIter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Value)> + 'a>;
504 /// A mutable iterator type over key/value pairs of an inline table.
505 pub type InlineTableIterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Value)> + 'a>;
506 
507 impl TableLike for InlineTable {
iter(&self) -> Iter<'_>508     fn iter(&self) -> Iter<'_> {
509         Box::new(self.items.iter().map(|(key, kv)| (&key[..], &kv.value)))
510     }
iter_mut(&mut self) -> IterMut<'_>511     fn iter_mut(&mut self) -> IterMut<'_> {
512         Box::new(
513             self.items
514                 .iter_mut()
515                 .map(|(_, kv)| (kv.key.as_mut(), &mut kv.value)),
516         )
517     }
clear(&mut self)518     fn clear(&mut self) {
519         self.clear();
520     }
entry<'a>(&'a mut self, key: &str) -> crate::Entry<'a>521     fn entry<'a>(&'a mut self, key: &str) -> crate::Entry<'a> {
522         // Accept a `&str` rather than an owned type to keep `InternalString`, well, internal
523         match self.items.entry(key.into()) {
524             indexmap::map::Entry::Occupied(entry) => {
525                 crate::Entry::Occupied(crate::OccupiedEntry { entry })
526             }
527             indexmap::map::Entry::Vacant(entry) => {
528                 crate::Entry::Vacant(crate::VacantEntry { entry, key: None })
529             }
530         }
531     }
entry_format<'a>(&'a mut self, key: &Key) -> crate::Entry<'a>532     fn entry_format<'a>(&'a mut self, key: &Key) -> crate::Entry<'a> {
533         // Accept a `&Key` to be consistent with `entry`
534         match self.items.entry(key.get().into()) {
535             indexmap::map::Entry::Occupied(entry) => {
536                 crate::Entry::Occupied(crate::OccupiedEntry { entry })
537             }
538             indexmap::map::Entry::Vacant(entry) => crate::Entry::Vacant(crate::VacantEntry {
539                 entry,
540                 key: Some(key.to_owned()),
541             }),
542         }
543     }
get<'s>(&'s self, key: &str) -> Option<&'s Item>544     fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
545         self.items.get(key).map(|kv| &kv.value)
546     }
get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item>547     fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
548         self.items.get_mut(key).map(|kv| &mut kv.value)
549     }
get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)>550     fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
551         self.get_key_value(key)
552     }
get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)>553     fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
554         self.get_key_value_mut(key)
555     }
contains_key(&self, key: &str) -> bool556     fn contains_key(&self, key: &str) -> bool {
557         self.contains_key(key)
558     }
insert(&mut self, key: &str, value: Item) -> Option<Item>559     fn insert(&mut self, key: &str, value: Item) -> Option<Item> {
560         self.insert(key, value.into_value().unwrap())
561             .map(Item::Value)
562     }
remove(&mut self, key: &str) -> Option<Item>563     fn remove(&mut self, key: &str) -> Option<Item> {
564         self.remove(key).map(Item::Value)
565     }
566 
get_values(&self) -> Vec<(Vec<&Key>, &Value)>567     fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
568         self.get_values()
569     }
fmt(&mut self)570     fn fmt(&mut self) {
571         self.fmt();
572     }
sort_values(&mut self)573     fn sort_values(&mut self) {
574         self.sort_values();
575     }
set_dotted(&mut self, yes: bool)576     fn set_dotted(&mut self, yes: bool) {
577         self.set_dotted(yes);
578     }
is_dotted(&self) -> bool579     fn is_dotted(&self) -> bool {
580         self.is_dotted()
581     }
582 
key(&self, key: &str) -> Option<&'_ Key>583     fn key(&self, key: &str) -> Option<&'_ Key> {
584         self.key(key)
585     }
key_mut(&mut self, key: &str) -> Option<KeyMut<'_>>586     fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
587         self.key_mut(key)
588     }
key_decor_mut(&mut self, key: &str) -> Option<&mut Decor>589     fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
590         #![allow(deprecated)]
591         self.key_decor_mut(key)
592     }
key_decor(&self, key: &str) -> Option<&Decor>593     fn key_decor(&self, key: &str) -> Option<&Decor> {
594         #![allow(deprecated)]
595         self.key_decor(key)
596     }
597 }
598 
599 // `{ key1 = value1, ... }`
600 pub(crate) const DEFAULT_INLINE_KEY_DECOR: (&str, &str) = (" ", " ");
601 
602 /// A view into a single location in a map, which may be vacant or occupied.
603 pub enum InlineEntry<'a> {
604     /// An occupied Entry.
605     Occupied(InlineOccupiedEntry<'a>),
606     /// A vacant Entry.
607     Vacant(InlineVacantEntry<'a>),
608 }
609 
610 impl<'a> InlineEntry<'a> {
611     /// Returns the entry key
612     ///
613     /// # Examples
614     ///
615     /// ```
616     /// use toml_edit::Table;
617     ///
618     /// let mut map = Table::new();
619     ///
620     /// assert_eq!("hello", map.entry("hello").key());
621     /// ```
key(&self) -> &str622     pub fn key(&self) -> &str {
623         match self {
624             InlineEntry::Occupied(e) => e.key(),
625             InlineEntry::Vacant(e) => e.key(),
626         }
627     }
628 
629     /// Ensures a value is in the entry by inserting the default if empty, and returns
630     /// a mutable reference to the value in the entry.
or_insert(self, default: Value) -> &'a mut Value631     pub fn or_insert(self, default: Value) -> &'a mut Value {
632         match self {
633             InlineEntry::Occupied(entry) => entry.into_mut(),
634             InlineEntry::Vacant(entry) => entry.insert(default),
635         }
636     }
637 
638     /// Ensures a value is in the entry by inserting the result of the default function if empty,
639     /// and returns a mutable reference to the value in the entry.
or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value640     pub fn or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value {
641         match self {
642             InlineEntry::Occupied(entry) => entry.into_mut(),
643             InlineEntry::Vacant(entry) => entry.insert(default()),
644         }
645     }
646 }
647 
648 /// A view into a single occupied location in a `IndexMap`.
649 pub struct InlineOccupiedEntry<'a> {
650     entry: indexmap::map::OccupiedEntry<'a, InternalString, TableKeyValue>,
651 }
652 
653 impl<'a> InlineOccupiedEntry<'a> {
654     /// Gets a reference to the entry key
655     ///
656     /// # Examples
657     ///
658     /// ```
659     /// use toml_edit::Table;
660     ///
661     /// let mut map = Table::new();
662     ///
663     /// assert_eq!("foo", map.entry("foo").key());
664     /// ```
key(&self) -> &str665     pub fn key(&self) -> &str {
666         self.entry.key().as_str()
667     }
668 
669     /// Gets a mutable reference to the entry key
key_mut(&mut self) -> KeyMut<'_>670     pub fn key_mut(&mut self) -> KeyMut<'_> {
671         self.entry.get_mut().key.as_mut()
672     }
673 
674     /// Gets a reference to the value in the entry.
get(&self) -> &Value675     pub fn get(&self) -> &Value {
676         self.entry.get().value.as_value().unwrap()
677     }
678 
679     /// Gets a mutable reference to the value in the entry.
get_mut(&mut self) -> &mut Value680     pub fn get_mut(&mut self) -> &mut Value {
681         self.entry.get_mut().value.as_value_mut().unwrap()
682     }
683 
684     /// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
685     /// with a lifetime bound to the map itself
into_mut(self) -> &'a mut Value686     pub fn into_mut(self) -> &'a mut Value {
687         self.entry.into_mut().value.as_value_mut().unwrap()
688     }
689 
690     /// Sets the value of the entry, and returns the entry's old value
insert(&mut self, value: Value) -> Value691     pub fn insert(&mut self, value: Value) -> Value {
692         let mut value = Item::Value(value);
693         std::mem::swap(&mut value, &mut self.entry.get_mut().value);
694         value.into_value().unwrap()
695     }
696 
697     /// Takes the value out of the entry, and returns it
remove(self) -> Value698     pub fn remove(self) -> Value {
699         self.entry.shift_remove().value.into_value().unwrap()
700     }
701 }
702 
703 /// A view into a single empty location in a `IndexMap`.
704 pub struct InlineVacantEntry<'a> {
705     entry: indexmap::map::VacantEntry<'a, InternalString, TableKeyValue>,
706     key: Option<Key>,
707 }
708 
709 impl<'a> InlineVacantEntry<'a> {
710     /// Gets a reference to the entry key
711     ///
712     /// # Examples
713     ///
714     /// ```
715     /// use toml_edit::Table;
716     ///
717     /// let mut map = Table::new();
718     ///
719     /// assert_eq!("foo", map.entry("foo").key());
720     /// ```
key(&self) -> &str721     pub fn key(&self) -> &str {
722         self.entry.key().as_str()
723     }
724 
725     /// Sets the value of the entry with the `VacantEntry`'s key,
726     /// and returns a mutable reference to it
insert(self, value: Value) -> &'a mut Value727     pub fn insert(self, value: Value) -> &'a mut Value {
728         let entry = self.entry;
729         let key = self.key.unwrap_or_else(|| Key::new(entry.key().as_str()));
730         let value = Item::Value(value);
731         entry
732             .insert(TableKeyValue::new(key, value))
733             .value
734             .as_value_mut()
735             .unwrap()
736     }
737 }
738