1use std::iter::FromIterator;
2
3use crate::key::Key;
4use crate::repr::Decor;
5use crate::table::{Iter, IterMut, KeyValuePairs, TableLike};
6use crate::{InternalString, Item, KeyMut, RawString, Table, Value};
7
8#[derive(Debug, Default, Clone)]
10pub struct InlineTable {
11 preamble: RawString,
13 pub(crate) implicit: bool,
15 decor: Decor,
17 pub(crate) span: Option<std::ops::Range<usize>>,
18 dotted: bool,
20 pub(crate) items: KeyValuePairs,
21}
22
23impl InlineTable {
27 pub fn new() -> Self {
29 Default::default()
30 }
31
32 pub(crate) fn with_pairs(items: KeyValuePairs) -> Self {
33 Self {
34 items,
35 ..Default::default()
36 }
37 }
38
39 pub fn into_table(self) -> Table {
41 let mut t = Table::with_pairs(self.items);
42 t.fmt();
43 t
44 }
45}
46
47impl InlineTable {
49 pub fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
53 let mut values = Vec::new();
54 let root = Vec::new();
55 self.append_values(&root, &mut values);
56 values
57 }
58
59 pub(crate) fn append_values<'s>(
60 &'s self,
61 parent: &[&'s Key],
62 values: &mut Vec<(Vec<&'s Key>, &'s Value)>,
63 ) {
64 for (key, value) in self.items.iter() {
65 let mut path = parent.to_vec();
66 path.push(key);
67 match value {
68 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
69 table.append_values(&path, values);
70 }
71 Item::Value(value) => {
72 values.push((path, value));
73 }
74 _ => {}
75 }
76 }
77 }
78
79 pub fn fmt(&mut self) {
81 decorate_inline_table(self);
82 }
83
84 pub fn sort_values(&mut self) {
92 self.items.sort_keys();
94 for value in self.items.values_mut() {
95 match value {
96 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
97 table.sort_values();
98 }
99 _ => {}
100 }
101 }
102 }
103
104 pub fn sort_values_by<F>(&mut self, mut compare: F)
115 where
116 F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering,
117 {
118 self.sort_values_by_internal(&mut compare);
119 }
120
121 fn sort_values_by_internal<F>(&mut self, compare: &mut F)
122 where
123 F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering,
124 {
125 let modified_cmp =
126 |key1: &Key, val1: &Item, key2: &Key, val2: &Item| -> std::cmp::Ordering {
127 match (val1.as_value(), val2.as_value()) {
128 (Some(v1), Some(v2)) => compare(key1, v1, key2, v2),
129 (Some(_), None) => std::cmp::Ordering::Greater,
130 (None, Some(_)) => std::cmp::Ordering::Less,
131 (None, None) => std::cmp::Ordering::Equal,
132 }
133 };
134
135 self.items.sort_by(modified_cmp);
136 for value in self.items.values_mut() {
137 match value {
138 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
139 table.sort_values_by_internal(compare);
140 }
141 _ => {}
142 }
143 }
144 }
145
146 pub(crate) fn set_implicit(&mut self, implicit: bool) {
168 self.implicit = implicit;
169 }
170
171 pub(crate) fn is_implicit(&self) -> bool {
173 self.implicit
174 }
175
176 pub fn set_dotted(&mut self, yes: bool) {
178 self.dotted = yes;
179 }
180
181 pub fn is_dotted(&self) -> bool {
183 self.dotted
184 }
185
186 pub fn decor_mut(&mut self) -> &mut Decor {
188 &mut self.decor
189 }
190
191 pub fn decor(&self) -> &Decor {
193 &self.decor
194 }
195
196 pub fn key(&self, key: &str) -> Option<&'_ Key> {
198 self.items.get_full(key).map(|(_, key, _)| key)
199 }
200
201 pub fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
203 use indexmap::map::MutableKeys;
204 self.items
205 .get_full_mut2(key)
206 .map(|(_, key, _)| key.as_mut())
207 }
208
209 #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
211 pub fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
212 #![allow(deprecated)]
213 use indexmap::map::MutableKeys;
214 self.items
215 .get_full_mut2(key)
216 .map(|(_, key, _)| key.leaf_decor_mut())
217 }
218
219 #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
221 pub fn key_decor(&self, key: &str) -> Option<&Decor> {
222 #![allow(deprecated)]
223 self.items.get_full(key).map(|(_, key, _)| key.leaf_decor())
224 }
225
226 pub fn set_preamble(&mut self, preamble: impl Into<RawString>) {
228 self.preamble = preamble.into();
229 }
230
231 pub fn preamble(&self) -> &RawString {
233 &self.preamble
234 }
235
236 pub fn span(&self) -> Option<std::ops::Range<usize>> {
240 self.span.clone()
241 }
242
243 pub(crate) fn despan(&mut self, input: &str) {
244 use indexmap::map::MutableKeys;
245 self.span = None;
246 self.decor.despan(input);
247 self.preamble.despan(input);
248 for (key, value) in self.items.iter_mut2() {
249 key.despan(input);
250 value.despan(input);
251 }
252 }
253}
254
255impl InlineTable {
256 pub fn iter(&self) -> InlineTableIter<'_> {
258 Box::new(
259 self.items
260 .iter()
261 .filter(|(_, value)| !value.is_none())
262 .map(|(key, value)| (key.get(), value.as_value().unwrap())),
263 )
264 }
265
266 pub fn iter_mut(&mut self) -> InlineTableIterMut<'_> {
268 use indexmap::map::MutableKeys;
269 Box::new(
270 self.items
271 .iter_mut2()
272 .filter(|(_, value)| value.is_value())
273 .map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap())),
274 )
275 }
276
277 pub fn len(&self) -> usize {
279 self.iter().count()
280 }
281
282 pub fn is_empty(&self) -> bool {
284 self.len() == 0
285 }
286
287 pub fn clear(&mut self) {
289 self.items.clear();
290 }
291
292 pub fn entry(&'_ mut self, key: impl Into<InternalString>) -> InlineEntry<'_> {
294 match self.items.entry(key.into().into()) {
295 indexmap::map::Entry::Occupied(mut entry) => {
296 let scratch = std::mem::take(entry.get_mut());
298 let scratch = Item::Value(
299 scratch
300 .into_value()
301 .unwrap_or_else(|_| Value::InlineTable(Default::default())),
304 );
305 *entry.get_mut() = scratch;
306
307 InlineEntry::Occupied(InlineOccupiedEntry { entry })
308 }
309 indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { entry }),
310 }
311 }
312
313 pub fn entry_format<'a>(&'a mut self, key: &Key) -> InlineEntry<'a> {
315 match self.items.entry(key.clone()) {
317 indexmap::map::Entry::Occupied(mut entry) => {
318 let scratch = std::mem::take(entry.get_mut());
320 let scratch = Item::Value(
321 scratch
322 .into_value()
323 .unwrap_or_else(|_| Value::InlineTable(Default::default())),
326 );
327 *entry.get_mut() = scratch;
328
329 InlineEntry::Occupied(InlineOccupiedEntry { entry })
330 }
331 indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { entry }),
332 }
333 }
334 pub fn get(&self, key: &str) -> Option<&Value> {
336 self.items.get(key).and_then(|value| value.as_value())
337 }
338
339 pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
341 self.items
342 .get_mut(key)
343 .and_then(|value| value.as_value_mut())
344 }
345
346 pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
348 self.items.get_full(key).and_then(|(_, key, value)| {
349 if !value.is_none() {
350 Some((key, value))
351 } else {
352 None
353 }
354 })
355 }
356
357 pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
359 use indexmap::map::MutableKeys;
360 self.items.get_full_mut2(key).and_then(|(_, key, value)| {
361 if !value.is_none() {
362 Some((key.as_mut(), value))
363 } else {
364 None
365 }
366 })
367 }
368
369 pub fn contains_key(&self, key: &str) -> bool {
371 if let Some(value) = self.items.get(key) {
372 value.is_value()
373 } else {
374 false
375 }
376 }
377
378 pub fn get_or_insert<V: Into<Value>>(
381 &mut self,
382 key: impl Into<InternalString>,
383 value: V,
384 ) -> &mut Value {
385 let key = key.into();
386 self.items
387 .entry(Key::new(key))
388 .or_insert(Item::Value(value.into()))
389 .as_value_mut()
390 .expect("non-value type in inline table")
391 }
392
393 pub fn insert(&mut self, key: impl Into<InternalString>, value: Value) -> Option<Value> {
395 use indexmap::map::MutableEntryKey;
396 let key = Key::new(key);
397 let value = Item::Value(value);
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(), value);
402 old.into_value().ok()
403 }
404 indexmap::map::Entry::Vacant(entry) => {
405 entry.insert(value);
406 None
407 }
408 }
409 }
410
411 pub fn insert_formatted(&mut self, key: &Key, value: Value) -> Option<Value> {
413 use indexmap::map::MutableEntryKey;
414 let value = Item::Value(value);
415 match self.items.entry(key.clone()) {
416 indexmap::map::Entry::Occupied(mut entry) => {
417 *entry.key_mut() = key.clone();
418 let old = std::mem::replace(entry.get_mut(), value);
419 old.into_value().ok()
420 }
421 indexmap::map::Entry::Vacant(entry) => {
422 entry.insert(value);
423 None
424 }
425 }
426 }
427
428 pub fn remove(&mut self, key: &str) -> Option<Value> {
430 self.items
431 .shift_remove(key)
432 .and_then(|value| value.into_value().ok())
433 }
434
435 pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Value)> {
437 self.items
438 .shift_remove_entry(key)
439 .and_then(|(key, value)| Some((key, value.into_value().ok()?)))
440 }
441
442 pub fn retain<F>(&mut self, mut keep: F)
449 where
450 F: FnMut(&str, &mut Value) -> bool,
451 {
452 self.items.retain(|key, item| {
453 item.as_value_mut()
454 .map(|value| keep(key, value))
455 .unwrap_or(false)
456 });
457 }
458}
459
460#[cfg(feature = "display")]
461impl std::fmt::Display for InlineTable {
462 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
463 crate::encode::encode_table(self, f, None, ("", ""))
464 }
465}
466
467impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for InlineTable {
468 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
469 for (key, value) in iter {
470 let key = key.into();
471 let value = Item::Value(value.into());
472 self.items.insert(key, value);
473 }
474 }
475}
476
477impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for InlineTable {
478 fn from_iter<I>(iter: I) -> Self
479 where
480 I: IntoIterator<Item = (K, V)>,
481 {
482 let mut table = InlineTable::new();
483 table.extend(iter);
484 table
485 }
486}
487
488impl IntoIterator for InlineTable {
489 type Item = (InternalString, Value);
490 type IntoIter = InlineTableIntoIter;
491
492 fn into_iter(self) -> Self::IntoIter {
493 Box::new(
494 self.items
495 .into_iter()
496 .filter(|(_, value)| value.is_value())
497 .map(|(key, value)| (key.into(), value.into_value().unwrap())),
498 )
499 }
500}
501
502impl<'s> IntoIterator for &'s InlineTable {
503 type Item = (&'s str, &'s Value);
504 type IntoIter = InlineTableIter<'s>;
505
506 fn into_iter(self) -> Self::IntoIter {
507 self.iter()
508 }
509}
510
511fn decorate_inline_table(table: &mut InlineTable) {
512 use indexmap::map::MutableKeys;
513 for (mut key, value) in table
514 .items
515 .iter_mut2()
516 .filter(|(_, value)| value.is_value())
517 .map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap()))
518 {
519 key.leaf_decor_mut().clear();
520 key.dotted_decor_mut().clear();
521 value.decor_mut().clear();
522 }
523}
524
525pub type InlineTableIntoIter = Box<dyn Iterator<Item = (InternalString, Value)>>;
527pub type InlineTableIter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Value)> + 'a>;
529pub type InlineTableIterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Value)> + 'a>;
531
532impl TableLike for InlineTable {
533 fn iter(&self) -> Iter<'_> {
534 Box::new(self.items.iter().map(|(key, value)| (key.get(), value)))
535 }
536 fn iter_mut(&mut self) -> IterMut<'_> {
537 use indexmap::map::MutableKeys;
538 Box::new(
539 self.items
540 .iter_mut2()
541 .map(|(key, value)| (key.as_mut(), value)),
542 )
543 }
544 fn clear(&mut self) {
545 self.clear();
546 }
547 fn entry<'a>(&'a mut self, key: &str) -> crate::Entry<'a> {
548 match self.items.entry(key.into()) {
550 indexmap::map::Entry::Occupied(entry) => {
551 crate::Entry::Occupied(crate::OccupiedEntry { entry })
552 }
553 indexmap::map::Entry::Vacant(entry) => {
554 crate::Entry::Vacant(crate::VacantEntry { entry })
555 }
556 }
557 }
558 fn entry_format<'a>(&'a mut self, key: &Key) -> crate::Entry<'a> {
559 match self.items.entry(key.get().into()) {
561 indexmap::map::Entry::Occupied(entry) => {
562 crate::Entry::Occupied(crate::OccupiedEntry { entry })
563 }
564 indexmap::map::Entry::Vacant(entry) => {
565 crate::Entry::Vacant(crate::VacantEntry { entry })
566 }
567 }
568 }
569 fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
570 self.items.get(key)
571 }
572 fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
573 self.items.get_mut(key)
574 }
575 fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
576 self.get_key_value(key)
577 }
578 fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
579 self.get_key_value_mut(key)
580 }
581 fn contains_key(&self, key: &str) -> bool {
582 self.contains_key(key)
583 }
584 fn insert(&mut self, key: &str, value: Item) -> Option<Item> {
585 self.insert(key, value.into_value().unwrap())
586 .map(Item::Value)
587 }
588 fn remove(&mut self, key: &str) -> Option<Item> {
589 self.remove(key).map(Item::Value)
590 }
591
592 fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
593 self.get_values()
594 }
595 fn fmt(&mut self) {
596 self.fmt();
597 }
598 fn sort_values(&mut self) {
599 self.sort_values();
600 }
601 fn set_dotted(&mut self, yes: bool) {
602 self.set_dotted(yes);
603 }
604 fn is_dotted(&self) -> bool {
605 self.is_dotted()
606 }
607
608 fn key(&self, key: &str) -> Option<&'_ Key> {
609 self.key(key)
610 }
611 fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
612 self.key_mut(key)
613 }
614 fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
615 #![allow(deprecated)]
616 self.key_decor_mut(key)
617 }
618 fn key_decor(&self, key: &str) -> Option<&Decor> {
619 #![allow(deprecated)]
620 self.key_decor(key)
621 }
622}
623
624pub(crate) const DEFAULT_INLINE_KEY_DECOR: (&str, &str) = (" ", " ");
626
627pub enum InlineEntry<'a> {
629 Occupied(InlineOccupiedEntry<'a>),
631 Vacant(InlineVacantEntry<'a>),
633}
634
635impl<'a> InlineEntry<'a> {
636 pub fn key(&self) -> &str {
648 match self {
649 InlineEntry::Occupied(e) => e.key(),
650 InlineEntry::Vacant(e) => e.key(),
651 }
652 }
653
654 pub fn or_insert(self, default: Value) -> &'a mut Value {
657 match self {
658 InlineEntry::Occupied(entry) => entry.into_mut(),
659 InlineEntry::Vacant(entry) => entry.insert(default),
660 }
661 }
662
663 pub fn or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value {
666 match self {
667 InlineEntry::Occupied(entry) => entry.into_mut(),
668 InlineEntry::Vacant(entry) => entry.insert(default()),
669 }
670 }
671}
672
673pub struct InlineOccupiedEntry<'a> {
675 entry: indexmap::map::OccupiedEntry<'a, Key, Item>,
676}
677
678impl<'a> InlineOccupiedEntry<'a> {
679 pub fn key(&self) -> &str {
691 self.entry.key().get()
692 }
693
694 pub fn key_mut(&mut self) -> KeyMut<'_> {
696 use indexmap::map::MutableEntryKey;
697 self.entry.key_mut().as_mut()
698 }
699
700 pub fn get(&self) -> &Value {
702 self.entry.get().as_value().unwrap()
703 }
704
705 pub fn get_mut(&mut self) -> &mut Value {
707 self.entry.get_mut().as_value_mut().unwrap()
708 }
709
710 pub fn into_mut(self) -> &'a mut Value {
713 self.entry.into_mut().as_value_mut().unwrap()
714 }
715
716 pub fn insert(&mut self, value: Value) -> Value {
718 let value = Item::Value(value);
719 self.entry.insert(value).into_value().unwrap()
720 }
721
722 pub fn remove(self) -> Value {
724 self.entry.shift_remove().into_value().unwrap()
725 }
726}
727
728pub struct InlineVacantEntry<'a> {
730 entry: indexmap::map::VacantEntry<'a, Key, Item>,
731}
732
733impl<'a> InlineVacantEntry<'a> {
734 pub fn key(&self) -> &str {
746 self.entry.key().get()
747 }
748
749 pub fn insert(self, value: Value) -> &'a mut Value {
752 let entry = self.entry;
753 let value = Item::Value(value);
754 entry.insert(value).as_value_mut().unwrap()
755 }
756}