1use std::iter::FromIterator;
2
3use crate::key::Key;
4use crate::repr::Decor;
5use crate::table::{Iter, IterMut, KeyValuePairs, TableLike};
6use crate::{Item, KeyMut, RawString, Table, Value};
7
8#[derive(Debug, Default, Clone)]
10pub struct InlineTable {
11 trailing: RawString,
14 trailing_comma: bool,
15 pub(crate) implicit: bool,
17 decor: Decor,
19 pub(crate) span: Option<std::ops::Range<usize>>,
20 dotted: bool,
22 pub(crate) items: KeyValuePairs,
23}
24
25impl InlineTable {
29 pub fn new() -> Self {
31 Default::default()
32 }
33
34 pub(crate) fn with_pairs(items: KeyValuePairs) -> Self {
35 Self {
36 items,
37 ..Default::default()
38 }
39 }
40
41 pub fn into_table(self) -> Table {
43 let mut t = Table::with_pairs(self.items);
44 t.fmt();
45 t
46 }
47}
48
49impl InlineTable {
51 pub fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
55 let mut values = Vec::new();
56 let root = Vec::new();
57 self.append_values(&root, &mut values);
58 values
59 }
60
61 pub(crate) fn append_values<'s>(
62 &'s self,
63 parent: &[&'s Key],
64 values: &mut Vec<(Vec<&'s Key>, &'s Value)>,
65 ) {
66 for (key, value) in self.items.iter() {
67 let mut path = parent.to_vec();
68 path.push(key);
69 match value {
70 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
71 table.append_values(&path, values);
72 }
73 Item::Value(value) => {
74 values.push((path, value));
75 }
76 Item::Table(table) => {
77 table.append_all_values(&path, values);
78 }
79 _ => {}
80 }
81 }
82 }
83
84 pub fn fmt(&mut self) {
86 decorate_inline_table(self);
87 }
88
89 pub fn set_trailing_comma(&mut self, yes: bool) {
91 self.trailing_comma = yes;
92 }
93
94 pub fn trailing_comma(&self) -> bool {
96 self.trailing_comma
97 }
98
99 pub fn set_trailing(&mut self, trailing: impl Into<RawString>) {
101 self.trailing = trailing.into();
102 }
103
104 pub fn trailing(&self) -> &RawString {
106 &self.trailing
107 }
108
109 pub fn sort_values(&mut self) {
117 self.items.sort_keys();
119 for value in self.items.values_mut() {
120 match value {
121 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
122 table.sort_values();
123 }
124 _ => {}
125 }
126 }
127 }
128
129 pub fn sort_values_by<F>(&mut self, mut compare: F)
140 where
141 F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering,
142 {
143 self.sort_values_by_internal(&mut compare);
144 }
145
146 fn sort_values_by_internal<F>(&mut self, compare: &mut F)
147 where
148 F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering,
149 {
150 let modified_cmp =
151 |key1: &Key, val1: &Item, key2: &Key, val2: &Item| -> std::cmp::Ordering {
152 match (val1.as_value(), val2.as_value()) {
153 (Some(v1), Some(v2)) => compare(key1, v1, key2, v2),
154 (Some(_), None) => std::cmp::Ordering::Greater,
155 (None, Some(_)) => std::cmp::Ordering::Less,
156 (None, None) => std::cmp::Ordering::Equal,
157 }
158 };
159
160 self.items.sort_by(modified_cmp);
161 for value in self.items.values_mut() {
162 match value {
163 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
164 table.sort_values_by_internal(compare);
165 }
166 _ => {}
167 }
168 }
169 }
170
171 pub(crate) fn set_implicit(&mut self, implicit: bool) {
193 self.implicit = implicit;
194 }
195
196 pub(crate) fn is_implicit(&self) -> bool {
198 self.implicit
199 }
200
201 pub fn set_dotted(&mut self, yes: bool) {
203 self.dotted = yes;
204 }
205
206 pub fn is_dotted(&self) -> bool {
208 self.dotted
209 }
210
211 pub fn decor_mut(&mut self) -> &mut Decor {
213 &mut self.decor
214 }
215
216 pub fn decor(&self) -> &Decor {
218 &self.decor
219 }
220
221 pub fn key(&self, key: &str) -> Option<&'_ Key> {
223 self.items.get_full(key).map(|(_, key, _)| key)
224 }
225
226 pub fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
228 use indexmap::map::MutableKeys;
229 self.items
230 .get_full_mut2(key)
231 .map(|(_, key, _)| key.as_mut())
232 }
233
234 pub fn span(&self) -> Option<std::ops::Range<usize>> {
238 self.span.clone()
239 }
240
241 pub(crate) fn despan(&mut self, input: &str) {
242 use indexmap::map::MutableKeys;
243 self.span = None;
244 self.decor.despan(input);
245 self.trailing.despan(input);
246 for (key, value) in self.items.iter_mut2() {
247 key.despan(input);
248 value.despan(input);
249 }
250 }
251}
252
253impl InlineTable {
254 pub fn iter(&self) -> InlineTableIter<'_> {
256 Box::new(
257 self.items
258 .iter()
259 .filter(|(_, value)| !value.is_none())
260 .map(|(key, value)| (key.get(), value.as_value().unwrap())),
261 )
262 }
263
264 pub fn iter_mut(&mut self) -> InlineTableIterMut<'_> {
266 use indexmap::map::MutableKeys;
267 Box::new(
268 self.items
269 .iter_mut2()
270 .filter(|(_, value)| value.is_value())
271 .map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap())),
272 )
273 }
274
275 pub fn len(&self) -> usize {
277 self.iter().count()
278 }
279
280 pub fn is_empty(&self) -> bool {
282 self.len() == 0
283 }
284
285 pub fn clear(&mut self) {
287 self.items.clear();
288 }
289
290 pub fn entry(&'_ mut self, key: impl Into<String>) -> InlineEntry<'_> {
292 match self.items.entry(key.into().into()) {
293 indexmap::map::Entry::Occupied(mut entry) => {
294 let scratch = std::mem::take(entry.get_mut());
296 let scratch = Item::Value(
297 scratch
298 .into_value()
299 .unwrap_or_else(|_| Value::InlineTable(Default::default())),
302 );
303 *entry.get_mut() = scratch;
304
305 InlineEntry::Occupied(InlineOccupiedEntry { entry })
306 }
307 indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { entry }),
308 }
309 }
310
311 pub fn entry_format<'a>(&'a mut self, key: &Key) -> InlineEntry<'a> {
313 match self.items.entry(key.clone()) {
315 indexmap::map::Entry::Occupied(mut entry) => {
316 let scratch = std::mem::take(entry.get_mut());
318 let scratch = Item::Value(
319 scratch
320 .into_value()
321 .unwrap_or_else(|_| Value::InlineTable(Default::default())),
324 );
325 *entry.get_mut() = scratch;
326
327 InlineEntry::Occupied(InlineOccupiedEntry { entry })
328 }
329 indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { entry }),
330 }
331 }
332 pub fn get(&self, key: &str) -> Option<&Value> {
334 self.items.get(key).and_then(|value| value.as_value())
335 }
336
337 pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
339 self.items
340 .get_mut(key)
341 .and_then(|value| value.as_value_mut())
342 }
343
344 pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
346 self.items.get_full(key).and_then(|(_, key, value)| {
347 if !value.is_none() {
348 Some((key, value))
349 } else {
350 None
351 }
352 })
353 }
354
355 pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
357 use indexmap::map::MutableKeys;
358 self.items.get_full_mut2(key).and_then(|(_, key, value)| {
359 if !value.is_none() {
360 Some((key.as_mut(), value))
361 } else {
362 None
363 }
364 })
365 }
366
367 pub fn contains_key(&self, key: &str) -> bool {
369 if let Some(value) = self.items.get(key) {
370 value.is_value()
371 } else {
372 false
373 }
374 }
375
376 pub fn get_or_insert<V: Into<Value>>(
379 &mut self,
380 key: impl Into<String>,
381 value: V,
382 ) -> &mut Value {
383 let key = key.into();
384 self.items
385 .entry(Key::new(key))
386 .or_insert(Item::Value(value.into()))
387 .as_value_mut()
388 .expect("non-value type in inline table")
389 }
390
391 pub fn insert(&mut self, key: impl Into<String>, value: Value) -> Option<Value> {
393 use indexmap::map::MutableEntryKey;
394 let key = Key::new(key);
395 let value = Item::Value(value);
396 match self.items.entry(key.clone()) {
397 indexmap::map::Entry::Occupied(mut entry) => {
398 entry.key_mut().fmt();
399 let old = std::mem::replace(entry.get_mut(), value);
400 old.into_value().ok()
401 }
402 indexmap::map::Entry::Vacant(entry) => {
403 entry.insert(value);
404 None
405 }
406 }
407 }
408
409 pub fn insert_formatted(&mut self, key: &Key, value: Value) -> Option<Value> {
411 use indexmap::map::MutableEntryKey;
412 let value = Item::Value(value);
413 match self.items.entry(key.clone()) {
414 indexmap::map::Entry::Occupied(mut entry) => {
415 *entry.key_mut() = key.clone();
416 let old = std::mem::replace(entry.get_mut(), value);
417 old.into_value().ok()
418 }
419 indexmap::map::Entry::Vacant(entry) => {
420 entry.insert(value);
421 None
422 }
423 }
424 }
425
426 pub fn remove(&mut self, key: &str) -> Option<Value> {
428 self.items
429 .shift_remove(key)
430 .and_then(|value| value.into_value().ok())
431 }
432
433 pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Value)> {
435 self.items
436 .shift_remove_entry(key)
437 .and_then(|(key, value)| Some((key, value.into_value().ok()?)))
438 }
439
440 pub fn retain<F>(&mut self, mut keep: F)
447 where
448 F: FnMut(&str, &mut Value) -> bool,
449 {
450 self.items.retain(|key, item| {
451 item.as_value_mut()
452 .map(|value| keep(key, value))
453 .unwrap_or(false)
454 });
455 }
456}
457
458#[cfg(feature = "display")]
459impl std::fmt::Display for InlineTable {
460 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
461 crate::encode::encode_table(self, f, None, ("", ""))
462 }
463}
464
465impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for InlineTable {
466 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
467 for (key, value) in iter {
468 let key = key.into();
469 let value = Item::Value(value.into());
470 self.items.insert(key, value);
471 }
472 }
473}
474
475impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for InlineTable {
476 fn from_iter<I>(iter: I) -> Self
477 where
478 I: IntoIterator<Item = (K, V)>,
479 {
480 let mut table = Self::new();
481 table.extend(iter);
482 table
483 }
484}
485
486impl IntoIterator for InlineTable {
487 type Item = (String, Value);
488 type IntoIter = InlineTableIntoIter;
489
490 fn into_iter(self) -> Self::IntoIter {
491 Box::new(
492 self.items
493 .into_iter()
494 .filter(|(_, value)| value.is_value())
495 .map(|(key, value)| (key.into(), value.into_value().unwrap())),
496 )
497 }
498}
499
500impl<'s> IntoIterator for &'s InlineTable {
501 type Item = (&'s str, &'s Value);
502 type IntoIter = InlineTableIter<'s>;
503
504 fn into_iter(self) -> Self::IntoIter {
505 self.iter()
506 }
507}
508
509fn decorate_inline_table(table: &mut InlineTable) {
510 use indexmap::map::MutableKeys;
511 for (mut key, value) in table
512 .items
513 .iter_mut2()
514 .filter(|(_, value)| value.is_value())
515 .map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap()))
516 {
517 key.leaf_decor_mut().clear();
518 key.dotted_decor_mut().clear();
519 value.decor_mut().clear();
520 }
521}
522
523pub type InlineTableIntoIter = Box<dyn Iterator<Item = (String, Value)>>;
525pub type InlineTableIter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Value)> + 'a>;
527pub type InlineTableIterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Value)> + 'a>;
529
530impl TableLike for InlineTable {
531 fn iter(&self) -> Iter<'_> {
532 Box::new(self.items.iter().map(|(key, value)| (key.get(), value)))
533 }
534 fn iter_mut(&mut self) -> IterMut<'_> {
535 use indexmap::map::MutableKeys;
536 Box::new(
537 self.items
538 .iter_mut2()
539 .map(|(key, value)| (key.as_mut(), value)),
540 )
541 }
542 fn clear(&mut self) {
543 self.clear();
544 }
545 fn entry<'a>(&'a mut self, key: &str) -> crate::Entry<'a> {
546 match self.items.entry(key.into()) {
548 indexmap::map::Entry::Occupied(entry) => {
549 crate::Entry::Occupied(crate::OccupiedEntry { entry })
550 }
551 indexmap::map::Entry::Vacant(entry) => {
552 crate::Entry::Vacant(crate::VacantEntry { entry })
553 }
554 }
555 }
556 fn entry_format<'a>(&'a mut self, key: &Key) -> crate::Entry<'a> {
557 match self.items.entry(key.get().into()) {
559 indexmap::map::Entry::Occupied(entry) => {
560 crate::Entry::Occupied(crate::OccupiedEntry { entry })
561 }
562 indexmap::map::Entry::Vacant(entry) => {
563 crate::Entry::Vacant(crate::VacantEntry { entry })
564 }
565 }
566 }
567 fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
568 self.items.get(key)
569 }
570 fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
571 self.items.get_mut(key)
572 }
573 fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
574 self.get_key_value(key)
575 }
576 fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
577 self.get_key_value_mut(key)
578 }
579 fn contains_key(&self, key: &str) -> bool {
580 self.contains_key(key)
581 }
582 fn insert(&mut self, key: &str, value: Item) -> Option<Item> {
583 self.insert(key, value.into_value().unwrap())
584 .map(Item::Value)
585 }
586 fn remove(&mut self, key: &str) -> Option<Item> {
587 self.remove(key).map(Item::Value)
588 }
589
590 fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
591 self.get_values()
592 }
593 fn fmt(&mut self) {
594 self.fmt();
595 }
596 fn sort_values(&mut self) {
597 self.sort_values();
598 }
599 fn set_dotted(&mut self, yes: bool) {
600 self.set_dotted(yes);
601 }
602 fn is_dotted(&self) -> bool {
603 self.is_dotted()
604 }
605
606 fn key(&self, key: &str) -> Option<&'_ Key> {
607 self.key(key)
608 }
609 fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
610 self.key_mut(key)
611 }
612}
613
614pub(crate) const DEFAULT_INLINE_KEY_DECOR: (&str, &str) = (" ", " ");
616
617pub enum InlineEntry<'a> {
619 Occupied(InlineOccupiedEntry<'a>),
621 Vacant(InlineVacantEntry<'a>),
623}
624
625impl<'a> InlineEntry<'a> {
626 pub fn key(&self) -> &str {
638 match self {
639 InlineEntry::Occupied(e) => e.key(),
640 InlineEntry::Vacant(e) => e.key(),
641 }
642 }
643
644 pub fn or_insert(self, default: Value) -> &'a mut Value {
647 match self {
648 InlineEntry::Occupied(entry) => entry.into_mut(),
649 InlineEntry::Vacant(entry) => entry.insert(default),
650 }
651 }
652
653 pub fn or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value {
656 match self {
657 InlineEntry::Occupied(entry) => entry.into_mut(),
658 InlineEntry::Vacant(entry) => entry.insert(default()),
659 }
660 }
661}
662
663pub struct InlineOccupiedEntry<'a> {
665 entry: indexmap::map::OccupiedEntry<'a, Key, Item>,
666}
667
668impl<'a> InlineOccupiedEntry<'a> {
669 pub fn key(&self) -> &str {
681 self.entry.key().get()
682 }
683
684 pub fn key_mut(&mut self) -> KeyMut<'_> {
686 use indexmap::map::MutableEntryKey;
687 self.entry.key_mut().as_mut()
688 }
689
690 pub fn get(&self) -> &Value {
692 self.entry.get().as_value().unwrap()
693 }
694
695 pub fn get_mut(&mut self) -> &mut Value {
697 self.entry.get_mut().as_value_mut().unwrap()
698 }
699
700 pub fn into_mut(self) -> &'a mut Value {
703 self.entry.into_mut().as_value_mut().unwrap()
704 }
705
706 pub fn insert(&mut self, value: Value) -> Value {
708 let value = Item::Value(value);
709 self.entry.insert(value).into_value().unwrap()
710 }
711
712 pub fn remove(self) -> Value {
714 self.entry.shift_remove().into_value().unwrap()
715 }
716}
717
718pub struct InlineVacantEntry<'a> {
720 entry: indexmap::map::VacantEntry<'a, Key, Item>,
721}
722
723impl<'a> InlineVacantEntry<'a> {
724 pub fn key(&self) -> &str {
736 self.entry.key().get()
737 }
738
739 pub fn insert(self, value: Value) -> &'a mut Value {
742 let entry = self.entry;
743 let value = Item::Value(value);
744 entry.insert(value).as_value_mut().unwrap()
745 }
746}