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 | /// Retains only the elements specified by the `keep` predicate. |
368 | /// |
369 | /// In other words, remove all pairs `(key, value)` for which |
370 | /// `keep(&key, &mut value)` returns `false`. |
371 | /// |
372 | /// The elements are visited in iteration order. |
373 | pub fn retain<F>(&mut self, mut keep: F) |
374 | where |
375 | F: FnMut(&str, &mut Value) -> bool, |
376 | { |
377 | self.items.retain(|key, item| { |
378 | item.value |
379 | .as_value_mut() |
380 | .map(|value| keep(key, value)) |
381 | .unwrap_or(false) |
382 | }); |
383 | } |
384 | } |
385 | |
386 | impl std::fmt::Display for InlineTable { |
387 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
388 | crate::encode::Encode::encode(self, buf:f, input:None, ("" , "" )) |
389 | } |
390 | } |
391 | |
392 | impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for InlineTable { |
393 | fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) { |
394 | for (key: K, value: V) in iter { |
395 | let key: Key = key.into(); |
396 | let value: Item = Item::Value(value.into()); |
397 | let value: TableKeyValue = TableKeyValue::new(key, value); |
398 | self.items |
399 | .insert(key:InternalString::from(value.key.get()), value); |
400 | } |
401 | } |
402 | } |
403 | |
404 | impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for InlineTable { |
405 | fn from_iter<I>(iter: I) -> Self |
406 | where |
407 | I: IntoIterator<Item = (K, V)>, |
408 | { |
409 | let mut table: InlineTable = InlineTable::new(); |
410 | table.extend(iter); |
411 | table |
412 | } |
413 | } |
414 | |
415 | impl IntoIterator for InlineTable { |
416 | type Item = (InternalString, Value); |
417 | type IntoIter = InlineTableIntoIter; |
418 | |
419 | fn into_iter(self) -> Self::IntoIter { |
420 | Box::new( |
421 | self.items |
422 | .into_iter() |
423 | .filter(|(_, kv: &TableKeyValue)| kv.value.is_value()) |
424 | .map(|(k: InternalString, kv: TableKeyValue)| (k, kv.value.into_value().unwrap())), |
425 | ) |
426 | } |
427 | } |
428 | |
429 | impl<'s> IntoIterator for &'s InlineTable { |
430 | type Item = (&'s str, &'s Value); |
431 | type IntoIter = InlineTableIter<'s>; |
432 | |
433 | fn into_iter(self) -> Self::IntoIter { |
434 | self.iter() |
435 | } |
436 | } |
437 | |
438 | fn decorate_inline_table(table: &mut InlineTable) { |
439 | for (key_decor: &mut Decor, value: &mut Value) in tableimpl Iterator |
440 | .items |
441 | .iter_mut() |
442 | .filter(|&(_, ref kv: &&mut TableKeyValue)| kv.value.is_value()) |
443 | .map(|(_, kv: &mut TableKeyValue)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap())) |
444 | { |
445 | key_decor.clear(); |
446 | value.decor_mut().clear(); |
447 | } |
448 | } |
449 | |
450 | /// An owned iterator type over key/value pairs of an inline table. |
451 | pub type InlineTableIntoIter = Box<dyn Iterator<Item = (InternalString, Value)>>; |
452 | /// An iterator type over key/value pairs of an inline table. |
453 | pub type InlineTableIter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Value)> + 'a>; |
454 | /// A mutable iterator type over key/value pairs of an inline table. |
455 | pub type InlineTableIterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Value)> + 'a>; |
456 | |
457 | impl TableLike for InlineTable { |
458 | fn iter(&self) -> Iter<'_> { |
459 | Box::new(self.items.iter().map(|(key, kv)| (&key[..], &kv.value))) |
460 | } |
461 | fn iter_mut(&mut self) -> IterMut<'_> { |
462 | Box::new( |
463 | self.items |
464 | .iter_mut() |
465 | .map(|(_, kv)| (kv.key.as_mut(), &mut kv.value)), |
466 | ) |
467 | } |
468 | fn clear(&mut self) { |
469 | self.clear(); |
470 | } |
471 | fn entry<'a>(&'a mut self, key: &str) -> crate::Entry<'a> { |
472 | // Accept a `&str` rather than an owned type to keep `InternalString`, well, internal |
473 | match self.items.entry(key.into()) { |
474 | indexmap::map::Entry::Occupied(entry) => { |
475 | crate::Entry::Occupied(crate::OccupiedEntry { entry }) |
476 | } |
477 | indexmap::map::Entry::Vacant(entry) => { |
478 | crate::Entry::Vacant(crate::VacantEntry { entry, key: None }) |
479 | } |
480 | } |
481 | } |
482 | fn entry_format<'a>(&'a mut self, key: &Key) -> crate::Entry<'a> { |
483 | // Accept a `&Key` to be consistent with `entry` |
484 | match self.items.entry(key.get().into()) { |
485 | indexmap::map::Entry::Occupied(entry) => { |
486 | crate::Entry::Occupied(crate::OccupiedEntry { entry }) |
487 | } |
488 | indexmap::map::Entry::Vacant(entry) => crate::Entry::Vacant(crate::VacantEntry { |
489 | entry, |
490 | key: Some(key.to_owned()), |
491 | }), |
492 | } |
493 | } |
494 | fn get<'s>(&'s self, key: &str) -> Option<&'s Item> { |
495 | self.items.get(key).map(|kv| &kv.value) |
496 | } |
497 | fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> { |
498 | self.items.get_mut(key).map(|kv| &mut kv.value) |
499 | } |
500 | fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> { |
501 | self.get_key_value(key) |
502 | } |
503 | fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> { |
504 | self.get_key_value_mut(key) |
505 | } |
506 | fn contains_key(&self, key: &str) -> bool { |
507 | self.contains_key(key) |
508 | } |
509 | fn insert(&mut self, key: &str, value: Item) -> Option<Item> { |
510 | self.insert(key, value.into_value().unwrap()) |
511 | .map(Item::Value) |
512 | } |
513 | fn remove(&mut self, key: &str) -> Option<Item> { |
514 | self.remove(key).map(Item::Value) |
515 | } |
516 | |
517 | fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> { |
518 | self.get_values() |
519 | } |
520 | fn fmt(&mut self) { |
521 | self.fmt() |
522 | } |
523 | fn sort_values(&mut self) { |
524 | self.sort_values() |
525 | } |
526 | fn set_dotted(&mut self, yes: bool) { |
527 | self.set_dotted(yes) |
528 | } |
529 | fn is_dotted(&self) -> bool { |
530 | self.is_dotted() |
531 | } |
532 | |
533 | fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> { |
534 | self.key_decor_mut(key) |
535 | } |
536 | fn key_decor(&self, key: &str) -> Option<&Decor> { |
537 | self.key_decor(key) |
538 | } |
539 | } |
540 | |
541 | // `{ key1 = value1, ... }` |
542 | pub(crate) const DEFAULT_INLINE_KEY_DECOR: (&str, &str) = (" " , " " ); |
543 | |
544 | /// A view into a single location in a map, which may be vacant or occupied. |
545 | pub enum InlineEntry<'a> { |
546 | /// An occupied Entry. |
547 | Occupied(InlineOccupiedEntry<'a>), |
548 | /// A vacant Entry. |
549 | Vacant(InlineVacantEntry<'a>), |
550 | } |
551 | |
552 | impl<'a> InlineEntry<'a> { |
553 | /// Returns the entry key |
554 | /// |
555 | /// # Examples |
556 | /// |
557 | /// ``` |
558 | /// use toml_edit::Table; |
559 | /// |
560 | /// let mut map = Table::new(); |
561 | /// |
562 | /// assert_eq!("hello" , map.entry("hello" ).key()); |
563 | /// ``` |
564 | pub fn key(&self) -> &str { |
565 | match self { |
566 | InlineEntry::Occupied(e) => e.key(), |
567 | InlineEntry::Vacant(e) => e.key(), |
568 | } |
569 | } |
570 | |
571 | /// Ensures a value is in the entry by inserting the default if empty, and returns |
572 | /// a mutable reference to the value in the entry. |
573 | pub fn or_insert(self, default: Value) -> &'a mut Value { |
574 | match self { |
575 | InlineEntry::Occupied(entry) => entry.into_mut(), |
576 | InlineEntry::Vacant(entry) => entry.insert(default), |
577 | } |
578 | } |
579 | |
580 | /// Ensures a value is in the entry by inserting the result of the default function if empty, |
581 | /// and returns a mutable reference to the value in the entry. |
582 | pub fn or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value { |
583 | match self { |
584 | InlineEntry::Occupied(entry) => entry.into_mut(), |
585 | InlineEntry::Vacant(entry) => entry.insert(default()), |
586 | } |
587 | } |
588 | } |
589 | |
590 | /// A view into a single occupied location in a `IndexMap`. |
591 | pub struct InlineOccupiedEntry<'a> { |
592 | entry: indexmap::map::OccupiedEntry<'a, InternalString, TableKeyValue>, |
593 | } |
594 | |
595 | impl<'a> InlineOccupiedEntry<'a> { |
596 | /// Gets a reference to the entry key |
597 | /// |
598 | /// # Examples |
599 | /// |
600 | /// ``` |
601 | /// use toml_edit::Table; |
602 | /// |
603 | /// let mut map = Table::new(); |
604 | /// |
605 | /// assert_eq!("foo" , map.entry("foo" ).key()); |
606 | /// ``` |
607 | pub fn key(&self) -> &str { |
608 | self.entry.key().as_str() |
609 | } |
610 | |
611 | /// Gets a mutable reference to the entry key |
612 | pub fn key_mut(&mut self) -> KeyMut<'_> { |
613 | self.entry.get_mut().key.as_mut() |
614 | } |
615 | |
616 | /// Gets a reference to the value in the entry. |
617 | pub fn get(&self) -> &Value { |
618 | self.entry.get().value.as_value().unwrap() |
619 | } |
620 | |
621 | /// Gets a mutable reference to the value in the entry. |
622 | pub fn get_mut(&mut self) -> &mut Value { |
623 | self.entry.get_mut().value.as_value_mut().unwrap() |
624 | } |
625 | |
626 | /// Converts the OccupiedEntry into a mutable reference to the value in the entry |
627 | /// with a lifetime bound to the map itself |
628 | pub fn into_mut(self) -> &'a mut Value { |
629 | self.entry.into_mut().value.as_value_mut().unwrap() |
630 | } |
631 | |
632 | /// Sets the value of the entry, and returns the entry's old value |
633 | pub fn insert(&mut self, value: Value) -> Value { |
634 | let mut value = Item::Value(value); |
635 | std::mem::swap(&mut value, &mut self.entry.get_mut().value); |
636 | value.into_value().unwrap() |
637 | } |
638 | |
639 | /// Takes the value out of the entry, and returns it |
640 | pub fn remove(self) -> Value { |
641 | self.entry.shift_remove().value.into_value().unwrap() |
642 | } |
643 | } |
644 | |
645 | /// A view into a single empty location in a `IndexMap`. |
646 | pub struct InlineVacantEntry<'a> { |
647 | entry: indexmap::map::VacantEntry<'a, InternalString, TableKeyValue>, |
648 | key: Option<Key>, |
649 | } |
650 | |
651 | impl<'a> InlineVacantEntry<'a> { |
652 | /// Gets a reference to the entry key |
653 | /// |
654 | /// # Examples |
655 | /// |
656 | /// ``` |
657 | /// use toml_edit::Table; |
658 | /// |
659 | /// let mut map = Table::new(); |
660 | /// |
661 | /// assert_eq!("foo" , map.entry("foo" ).key()); |
662 | /// ``` |
663 | pub fn key(&self) -> &str { |
664 | self.entry.key().as_str() |
665 | } |
666 | |
667 | /// Sets the value of the entry with the VacantEntry's key, |
668 | /// and returns a mutable reference to it |
669 | pub fn insert(self, value: Value) -> &'a mut Value { |
670 | let entry = self.entry; |
671 | let key = self.key.unwrap_or_else(|| Key::new(entry.key().as_str())); |
672 | let value = Item::Value(value); |
673 | entry |
674 | .insert(TableKeyValue::new(key, value)) |
675 | .value |
676 | .as_value_mut() |
677 | .unwrap() |
678 | } |
679 | } |
680 | |