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