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