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 | // prefix before `{` and suffix after `}` |
15 | decor: Decor, |
16 | pub(crate) span: Option<std::ops::Range<usize>>, |
17 | // whether this is a proxy for dotted keys |
18 | dotted: bool, |
19 | pub(crate) items: KeyValuePairs, |
20 | } |
21 | |
22 | /// Constructors |
23 | /// |
24 | /// See also `FromIterator` |
25 | impl InlineTable { |
26 | /// Creates an empty table. |
27 | pub fn new() -> Self { |
28 | Default::default() |
29 | } |
30 | |
31 | pub(crate) fn with_pairs(items: KeyValuePairs) -> Self { |
32 | Self { |
33 | items, |
34 | ..Default::default() |
35 | } |
36 | } |
37 | |
38 | /// Convert to a table |
39 | pub fn into_table(self) -> Table { |
40 | let mut t: Table = Table::with_pairs(self.items); |
41 | t.fmt(); |
42 | t |
43 | } |
44 | } |
45 | |
46 | /// Formatting |
47 | impl InlineTable { |
48 | /// Get key/values for values that are visually children of this table |
49 | /// |
50 | /// For example, this will return dotted keys |
51 | pub fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> { |
52 | let mut values = Vec::new(); |
53 | let root = Vec::new(); |
54 | self.append_values(&root, &mut values); |
55 | values |
56 | } |
57 | |
58 | pub(crate) fn append_values<'s, 'c>( |
59 | &'s self, |
60 | parent: &[&'s Key], |
61 | values: &'c mut Vec<(Vec<&'s Key>, &'s Value)>, |
62 | ) { |
63 | for value in self.items.values() { |
64 | let mut path = parent.to_vec(); |
65 | path.push(&value.key); |
66 | match &value.value { |
67 | Item::Value(Value::InlineTable(table)) if table.is_dotted() => { |
68 | table.append_values(&path, values); |
69 | } |
70 | Item::Value(value) => { |
71 | values.push((path, value)); |
72 | } |
73 | _ => {} |
74 | } |
75 | } |
76 | } |
77 | |
78 | /// Auto formats the table. |
79 | pub fn fmt(&mut self) { |
80 | decorate_inline_table(self); |
81 | } |
82 | |
83 | /// Sorts the key/value pairs by key. |
84 | pub fn sort_values(&mut self) { |
85 | // Assuming standard tables have their position set and this won't negatively impact them |
86 | self.items.sort_keys(); |
87 | for kv in self.items.values_mut() { |
88 | match &mut kv.value { |
89 | Item::Value(Value::InlineTable(table)) if table.is_dotted() => { |
90 | table.sort_values(); |
91 | } |
92 | _ => {} |
93 | } |
94 | } |
95 | } |
96 | |
97 | /// Sort Key/Value Pairs of the table using the using the comparison function `compare`. |
98 | /// |
99 | /// The comparison function receives two key and value pairs to compare (you can sort by keys or |
100 | /// values or their combination as needed). |
101 | pub fn sort_values_by<F>(&mut self, mut compare: F) |
102 | where |
103 | F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering, |
104 | { |
105 | self.sort_values_by_internal(&mut compare); |
106 | } |
107 | |
108 | fn sort_values_by_internal<F>(&mut self, compare: &mut F) |
109 | where |
110 | F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering, |
111 | { |
112 | let modified_cmp = |_: &InternalString, |
113 | val1: &TableKeyValue, |
114 | _: &InternalString, |
115 | val2: &TableKeyValue| |
116 | -> std::cmp::Ordering { |
117 | match (val1.value.as_value(), val2.value.as_value()) { |
118 | (Some(v1), Some(v2)) => compare(&val1.key, v1, &val2.key, v2), |
119 | (Some(_), None) => std::cmp::Ordering::Greater, |
120 | (None, Some(_)) => std::cmp::Ordering::Less, |
121 | (None, None) => std::cmp::Ordering::Equal, |
122 | } |
123 | }; |
124 | |
125 | self.items.sort_by(modified_cmp); |
126 | for kv in self.items.values_mut() { |
127 | match &mut kv.value { |
128 | Item::Value(Value::InlineTable(table)) if table.is_dotted() => { |
129 | table.sort_values_by_internal(compare); |
130 | } |
131 | _ => {} |
132 | } |
133 | } |
134 | } |
135 | |
136 | /// Change this table's dotted status |
137 | pub fn set_dotted(&mut self, yes: bool) { |
138 | self.dotted = yes; |
139 | } |
140 | |
141 | /// Check if this is a wrapper for dotted keys, rather than a standard table |
142 | pub fn is_dotted(&self) -> bool { |
143 | self.dotted |
144 | } |
145 | |
146 | /// Returns the surrounding whitespace |
147 | pub fn decor_mut(&mut self) -> &mut Decor { |
148 | &mut self.decor |
149 | } |
150 | |
151 | /// Returns the surrounding whitespace |
152 | pub fn decor(&self) -> &Decor { |
153 | &self.decor |
154 | } |
155 | |
156 | /// Returns the decor associated with a given key of the table. |
157 | pub fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> { |
158 | self.items.get_mut(key).map(|kv| &mut kv.key.decor) |
159 | } |
160 | |
161 | /// Returns the decor associated with a given key of the table. |
162 | pub fn key_decor(&self, key: &str) -> Option<&Decor> { |
163 | self.items.get(key).map(|kv| &kv.key.decor) |
164 | } |
165 | |
166 | /// Set whitespace after before element |
167 | pub fn set_preamble(&mut self, preamble: impl Into<RawString>) { |
168 | self.preamble = preamble.into(); |
169 | } |
170 | |
171 | /// Whitespace after before element |
172 | pub fn preamble(&self) -> &RawString { |
173 | &self.preamble |
174 | } |
175 | |
176 | /// Returns the location within the original document |
177 | pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { |
178 | self.span.clone() |
179 | } |
180 | |
181 | pub(crate) fn despan(&mut self, input: &str) { |
182 | self.span = None; |
183 | self.decor.despan(input); |
184 | self.preamble.despan(input); |
185 | for kv in self.items.values_mut() { |
186 | kv.key.despan(input); |
187 | kv.value.despan(input); |
188 | } |
189 | } |
190 | } |
191 | |
192 | impl InlineTable { |
193 | /// Returns an iterator over key/value pairs. |
194 | pub fn iter(&self) -> InlineTableIter<'_> { |
195 | Box::new( |
196 | self.items |
197 | .iter() |
198 | .filter(|&(_, kv)| kv.value.is_value()) |
199 | .map(|(k, kv)| (&k[..], kv.value.as_value().unwrap())), |
200 | ) |
201 | } |
202 | |
203 | /// Returns an iterator over key/value pairs. |
204 | pub fn iter_mut(&mut self) -> InlineTableIterMut<'_> { |
205 | Box::new( |
206 | self.items |
207 | .iter_mut() |
208 | .filter(|(_, kv)| kv.value.is_value()) |
209 | .map(|(_, kv)| (kv.key.as_mut(), kv.value.as_value_mut().unwrap())), |
210 | ) |
211 | } |
212 | |
213 | /// Returns the number of key/value pairs. |
214 | pub fn len(&self) -> usize { |
215 | self.iter().count() |
216 | } |
217 | |
218 | /// Returns true iff the table is empty. |
219 | pub fn is_empty(&self) -> bool { |
220 | self.len() == 0 |
221 | } |
222 | |
223 | /// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse. |
224 | pub fn clear(&mut self) { |
225 | self.items.clear() |
226 | } |
227 | |
228 | /// Gets the given key's corresponding entry in the Table for in-place manipulation. |
229 | pub fn entry(&'_ mut self, key: impl Into<InternalString>) -> InlineEntry<'_> { |
230 | match self.items.entry(key.into()) { |
231 | indexmap::map::Entry::Occupied(mut entry) => { |
232 | // Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code. |
233 | let scratch = std::mem::take(&mut entry.get_mut().value); |
234 | let scratch = Item::Value( |
235 | scratch |
236 | .into_value() |
237 | // HACK: `Item::None` is a corner case of a corner case, let's just pick a |
238 | // "safe" value |
239 | .unwrap_or_else(|_| Value::InlineTable(Default::default())), |
240 | ); |
241 | entry.get_mut().value = scratch; |
242 | |
243 | InlineEntry::Occupied(InlineOccupiedEntry { entry }) |
244 | } |
245 | indexmap::map::Entry::Vacant(entry) => { |
246 | InlineEntry::Vacant(InlineVacantEntry { entry, key: None }) |
247 | } |
248 | } |
249 | } |
250 | |
251 | /// Gets the given key's corresponding entry in the Table for in-place manipulation. |
252 | pub fn entry_format<'a>(&'a mut self, key: &Key) -> InlineEntry<'a> { |
253 | // Accept a `&Key` to be consistent with `entry` |
254 | match self.items.entry(key.get().into()) { |
255 | indexmap::map::Entry::Occupied(mut entry) => { |
256 | // Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code. |
257 | let scratch = std::mem::take(&mut entry.get_mut().value); |
258 | let scratch = Item::Value( |
259 | scratch |
260 | .into_value() |
261 | // HACK: `Item::None` is a corner case of a corner case, let's just pick a |
262 | // "safe" value |
263 | .unwrap_or_else(|_| Value::InlineTable(Default::default())), |
264 | ); |
265 | entry.get_mut().value = scratch; |
266 | |
267 | InlineEntry::Occupied(InlineOccupiedEntry { entry }) |
268 | } |
269 | indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { |
270 | entry, |
271 | key: Some(key.clone()), |
272 | }), |
273 | } |
274 | } |
275 | /// Return an optional reference to the value at the given the key. |
276 | pub fn get(&self, key: &str) -> Option<&Value> { |
277 | self.items.get(key).and_then(|kv| kv.value.as_value()) |
278 | } |
279 | |
280 | /// Return an optional mutable reference to the value at the given the key. |
281 | pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> { |
282 | self.items |
283 | .get_mut(key) |
284 | .and_then(|kv| kv.value.as_value_mut()) |
285 | } |
286 | |
287 | /// Return references to the key-value pair stored for key, if it is present, else None. |
288 | pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { |
289 | self.items.get(key).and_then(|kv| { |
290 | if !kv.value.is_none() { |
291 | Some((&kv.key, &kv.value)) |
292 | } else { |
293 | None |
294 | } |
295 | }) |
296 | } |
297 | |
298 | /// Return mutable references to the key-value pair stored for key, if it is present, else None. |
299 | pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { |
300 | self.items.get_mut(key).and_then(|kv| { |
301 | if !kv.value.is_none() { |
302 | Some((kv.key.as_mut(), &mut kv.value)) |
303 | } else { |
304 | None |
305 | } |
306 | }) |
307 | } |
308 | |
309 | /// Returns true iff the table contains given key. |
310 | pub fn contains_key(&self, key: &str) -> bool { |
311 | if let Some(kv) = self.items.get(key) { |
312 | kv.value.is_value() |
313 | } else { |
314 | false |
315 | } |
316 | } |
317 | |
318 | /// Inserts a key/value pair if the table does not contain the key. |
319 | /// Returns a mutable reference to the corresponding value. |
320 | pub fn get_or_insert<V: Into<Value>>( |
321 | &mut self, |
322 | key: impl Into<InternalString>, |
323 | value: V, |
324 | ) -> &mut Value { |
325 | let key = key.into(); |
326 | self.items |
327 | .entry(key.clone()) |
328 | .or_insert(TableKeyValue::new(Key::new(key), Item::Value(value.into()))) |
329 | .value |
330 | .as_value_mut() |
331 | .expect("non-value type in inline table" ) |
332 | } |
333 | |
334 | /// Inserts a key-value pair into the map. |
335 | pub fn insert(&mut self, key: impl Into<InternalString>, value: Value) -> Option<Value> { |
336 | let key = key.into(); |
337 | let kv = TableKeyValue::new(Key::new(key.clone()), Item::Value(value)); |
338 | self.items |
339 | .insert(key, kv) |
340 | .and_then(|kv| kv.value.into_value().ok()) |
341 | } |
342 | |
343 | /// Inserts a key-value pair into the map. |
344 | pub fn insert_formatted(&mut self, key: &Key, value: Value) -> Option<Value> { |
345 | let kv = TableKeyValue::new(key.to_owned(), Item::Value(value)); |
346 | self.items |
347 | .insert(InternalString::from(key.get()), kv) |
348 | .filter(|kv| kv.value.is_value()) |
349 | .map(|kv| kv.value.into_value().unwrap()) |
350 | } |
351 | |
352 | /// Removes an item given the key. |
353 | pub fn remove(&mut self, key: &str) -> Option<Value> { |
354 | self.items |
355 | .shift_remove(key) |
356 | .and_then(|kv| kv.value.into_value().ok()) |
357 | } |
358 | |
359 | /// Removes a key from the map, returning the stored key and value if the key was previously in the map. |
360 | pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Value)> { |
361 | self.items.shift_remove(key).and_then(|kv| { |
362 | let key = kv.key; |
363 | kv.value.into_value().ok().map(|value| (key, value)) |
364 | }) |
365 | } |
366 | } |
367 | |
368 | impl std::fmt::Display for InlineTable { |
369 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
370 | crate::encode::Encode::encode(self, buf:f, input:None, ("" , "" )) |
371 | } |
372 | } |
373 | |
374 | impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for InlineTable { |
375 | fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) { |
376 | for (key: K, value: V) in iter { |
377 | let key: Key = key.into(); |
378 | let value: Item = Item::Value(value.into()); |
379 | let value: TableKeyValue = TableKeyValue::new(key, value); |
380 | self.items |
381 | .insert(key:InternalString::from(value.key.get()), value); |
382 | } |
383 | } |
384 | } |
385 | |
386 | impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for InlineTable { |
387 | fn from_iter<I>(iter: I) -> Self |
388 | where |
389 | I: IntoIterator<Item = (K, V)>, |
390 | { |
391 | let mut table: InlineTable = InlineTable::new(); |
392 | table.extend(iter); |
393 | table |
394 | } |
395 | } |
396 | |
397 | impl IntoIterator for InlineTable { |
398 | type Item = (InternalString, Value); |
399 | type IntoIter = InlineTableIntoIter; |
400 | |
401 | fn into_iter(self) -> Self::IntoIter { |
402 | Box::new( |
403 | self.items |
404 | .into_iter() |
405 | .filter(|(_, kv: &TableKeyValue)| kv.value.is_value()) |
406 | .map(|(k: InternalString, kv: TableKeyValue)| (k, kv.value.into_value().unwrap())), |
407 | ) |
408 | } |
409 | } |
410 | |
411 | impl<'s> IntoIterator for &'s InlineTable { |
412 | type Item = (&'s str, &'s Value); |
413 | type IntoIter = InlineTableIter<'s>; |
414 | |
415 | fn into_iter(self) -> Self::IntoIter { |
416 | self.iter() |
417 | } |
418 | } |
419 | |
420 | fn decorate_inline_table(table: &mut InlineTable) { |
421 | for (key_decor: &mut Decor, value: &mut Value) in tableimpl Iterator |
422 | .items |
423 | .iter_mut() |
424 | .filter(|&(_, ref kv: &&mut TableKeyValue)| kv.value.is_value()) |
425 | .map(|(_, kv: &mut TableKeyValue)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap())) |
426 | { |
427 | key_decor.clear(); |
428 | value.decor_mut().clear(); |
429 | } |
430 | } |
431 | |
432 | /// An owned iterator type over key/value pairs of an inline table. |
433 | pub type InlineTableIntoIter = Box<dyn Iterator<Item = (InternalString, Value)>>; |
434 | /// An iterator type over key/value pairs of an inline table. |
435 | pub type InlineTableIter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Value)> + 'a>; |
436 | /// A mutable iterator type over key/value pairs of an inline table. |
437 | pub type InlineTableIterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Value)> + 'a>; |
438 | |
439 | impl TableLike for InlineTable { |
440 | fn iter(&self) -> Iter<'_> { |
441 | Box::new(self.items.iter().map(|(key, kv)| (&key[..], &kv.value))) |
442 | } |
443 | fn iter_mut(&mut self) -> IterMut<'_> { |
444 | Box::new( |
445 | self.items |
446 | .iter_mut() |
447 | .map(|(_, kv)| (kv.key.as_mut(), &mut kv.value)), |
448 | ) |
449 | } |
450 | fn clear(&mut self) { |
451 | self.clear(); |
452 | } |
453 | fn entry<'a>(&'a mut self, key: &str) -> crate::Entry<'a> { |
454 | // Accept a `&str` rather than an owned type to keep `InternalString`, well, internal |
455 | match self.items.entry(key.into()) { |
456 | indexmap::map::Entry::Occupied(entry) => { |
457 | crate::Entry::Occupied(crate::OccupiedEntry { entry }) |
458 | } |
459 | indexmap::map::Entry::Vacant(entry) => { |
460 | crate::Entry::Vacant(crate::VacantEntry { entry, key: None }) |
461 | } |
462 | } |
463 | } |
464 | fn entry_format<'a>(&'a mut self, key: &Key) -> crate::Entry<'a> { |
465 | // Accept a `&Key` to be consistent with `entry` |
466 | match self.items.entry(key.get().into()) { |
467 | indexmap::map::Entry::Occupied(entry) => { |
468 | crate::Entry::Occupied(crate::OccupiedEntry { entry }) |
469 | } |
470 | indexmap::map::Entry::Vacant(entry) => crate::Entry::Vacant(crate::VacantEntry { |
471 | entry, |
472 | key: Some(key.to_owned()), |
473 | }), |
474 | } |
475 | } |
476 | fn get<'s>(&'s self, key: &str) -> Option<&'s Item> { |
477 | self.items.get(key).map(|kv| &kv.value) |
478 | } |
479 | fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> { |
480 | self.items.get_mut(key).map(|kv| &mut kv.value) |
481 | } |
482 | fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { |
483 | self.get_key_value(key) |
484 | } |
485 | fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { |
486 | self.get_key_value_mut(key) |
487 | } |
488 | fn contains_key(&self, key: &str) -> bool { |
489 | self.contains_key(key) |
490 | } |
491 | fn insert(&mut self, key: &str, value: Item) -> Option<Item> { |
492 | self.insert(key, value.into_value().unwrap()) |
493 | .map(Item::Value) |
494 | } |
495 | fn remove(&mut self, key: &str) -> Option<Item> { |
496 | self.remove(key).map(Item::Value) |
497 | } |
498 | |
499 | fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> { |
500 | self.get_values() |
501 | } |
502 | fn fmt(&mut self) { |
503 | self.fmt() |
504 | } |
505 | fn sort_values(&mut self) { |
506 | self.sort_values() |
507 | } |
508 | fn set_dotted(&mut self, yes: bool) { |
509 | self.set_dotted(yes) |
510 | } |
511 | fn is_dotted(&self) -> bool { |
512 | self.is_dotted() |
513 | } |
514 | |
515 | fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> { |
516 | self.key_decor_mut(key) |
517 | } |
518 | fn key_decor(&self, key: &str) -> Option<&Decor> { |
519 | self.key_decor(key) |
520 | } |
521 | } |
522 | |
523 | // `{ key1 = value1, ... }` |
524 | pub(crate) const DEFAULT_INLINE_KEY_DECOR: (&str, &str) = (" " , " " ); |
525 | |
526 | /// A view into a single location in a map, which may be vacant or occupied. |
527 | pub enum InlineEntry<'a> { |
528 | /// An occupied Entry. |
529 | Occupied(InlineOccupiedEntry<'a>), |
530 | /// A vacant Entry. |
531 | Vacant(InlineVacantEntry<'a>), |
532 | } |
533 | |
534 | impl<'a> InlineEntry<'a> { |
535 | /// Returns the entry key |
536 | /// |
537 | /// # Examples |
538 | /// |
539 | /// ``` |
540 | /// use toml_edit::Table; |
541 | /// |
542 | /// let mut map = Table::new(); |
543 | /// |
544 | /// assert_eq!("hello" , map.entry("hello" ).key()); |
545 | /// ``` |
546 | pub fn key(&self) -> &str { |
547 | match self { |
548 | InlineEntry::Occupied(e) => e.key(), |
549 | InlineEntry::Vacant(e) => e.key(), |
550 | } |
551 | } |
552 | |
553 | /// Ensures a value is in the entry by inserting the default if empty, and returns |
554 | /// a mutable reference to the value in the entry. |
555 | pub fn or_insert(self, default: Value) -> &'a mut Value { |
556 | match self { |
557 | InlineEntry::Occupied(entry) => entry.into_mut(), |
558 | InlineEntry::Vacant(entry) => entry.insert(default), |
559 | } |
560 | } |
561 | |
562 | /// Ensures a value is in the entry by inserting the result of the default function if empty, |
563 | /// and returns a mutable reference to the value in the entry. |
564 | pub fn or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value { |
565 | match self { |
566 | InlineEntry::Occupied(entry) => entry.into_mut(), |
567 | InlineEntry::Vacant(entry) => entry.insert(default()), |
568 | } |
569 | } |
570 | } |
571 | |
572 | /// A view into a single occupied location in a `IndexMap`. |
573 | pub struct InlineOccupiedEntry<'a> { |
574 | entry: indexmap::map::OccupiedEntry<'a, InternalString, TableKeyValue>, |
575 | } |
576 | |
577 | impl<'a> InlineOccupiedEntry<'a> { |
578 | /// Gets a reference to the entry key |
579 | /// |
580 | /// # Examples |
581 | /// |
582 | /// ``` |
583 | /// use toml_edit::Table; |
584 | /// |
585 | /// let mut map = Table::new(); |
586 | /// |
587 | /// assert_eq!("foo" , map.entry("foo" ).key()); |
588 | /// ``` |
589 | pub fn key(&self) -> &str { |
590 | self.entry.key().as_str() |
591 | } |
592 | |
593 | /// Gets a mutable reference to the entry key |
594 | pub fn key_mut(&mut self) -> KeyMut<'_> { |
595 | self.entry.get_mut().key.as_mut() |
596 | } |
597 | |
598 | /// Gets a reference to the value in the entry. |
599 | pub fn get(&self) -> &Value { |
600 | self.entry.get().value.as_value().unwrap() |
601 | } |
602 | |
603 | /// Gets a mutable reference to the value in the entry. |
604 | pub fn get_mut(&mut self) -> &mut Value { |
605 | self.entry.get_mut().value.as_value_mut().unwrap() |
606 | } |
607 | |
608 | /// Converts the OccupiedEntry into a mutable reference to the value in the entry |
609 | /// with a lifetime bound to the map itself |
610 | pub fn into_mut(self) -> &'a mut Value { |
611 | self.entry.into_mut().value.as_value_mut().unwrap() |
612 | } |
613 | |
614 | /// Sets the value of the entry, and returns the entry's old value |
615 | pub fn insert(&mut self, value: Value) -> Value { |
616 | let mut value = Item::Value(value); |
617 | std::mem::swap(&mut value, &mut self.entry.get_mut().value); |
618 | value.into_value().unwrap() |
619 | } |
620 | |
621 | /// Takes the value out of the entry, and returns it |
622 | pub fn remove(self) -> Value { |
623 | self.entry.shift_remove().value.into_value().unwrap() |
624 | } |
625 | } |
626 | |
627 | /// A view into a single empty location in a `IndexMap`. |
628 | pub struct InlineVacantEntry<'a> { |
629 | entry: indexmap::map::VacantEntry<'a, InternalString, TableKeyValue>, |
630 | key: Option<Key>, |
631 | } |
632 | |
633 | impl<'a> InlineVacantEntry<'a> { |
634 | /// Gets a reference to the entry key |
635 | /// |
636 | /// # Examples |
637 | /// |
638 | /// ``` |
639 | /// use toml_edit::Table; |
640 | /// |
641 | /// let mut map = Table::new(); |
642 | /// |
643 | /// assert_eq!("foo" , map.entry("foo" ).key()); |
644 | /// ``` |
645 | pub fn key(&self) -> &str { |
646 | self.entry.key().as_str() |
647 | } |
648 | |
649 | /// Sets the value of the entry with the VacantEntry's key, |
650 | /// and returns a mutable reference to it |
651 | pub fn insert(self, value: Value) -> &'a mut Value { |
652 | let entry = self.entry; |
653 | let key = self.key.unwrap_or_else(|| Key::new(entry.key().as_str())); |
654 | let value = Item::Value(value); |
655 | entry |
656 | .insert(TableKeyValue::new(key, value)) |
657 | .value |
658 | .as_value_mut() |
659 | .unwrap() |
660 | } |
661 | } |
662 | |