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