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 mut root = Vec::new();
57 self.append_values(&mut root, &mut values);
58 values
59 }
60
61 pub(crate) fn append_values<'s>(
66 &'s self,
67 path: &mut Vec<&'s Key>,
68 values: &mut Vec<(Vec<&'s Key>, &'s Value)>,
69 ) {
70 for (key, value) in self.items.iter() {
71 path.push(key);
72 match value {
73 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
74 table.append_values(path, values);
75 }
76 Item::Value(value) => {
77 values.push((path.clone(), value));
78 }
79 Item::Table(table) => {
80 table.append_all_values(path, values);
81 }
82 _ => {}
83 }
84 path.pop();
85 }
86 }
87
88 pub fn fmt(&mut self) {
90 decorate_inline_table(self);
91 }
92
93 pub fn set_trailing_comma(&mut self, yes: bool) {
95 self.trailing_comma = yes;
96 }
97
98 pub fn trailing_comma(&self) -> bool {
100 self.trailing_comma
101 }
102
103 pub fn set_trailing(&mut self, trailing: impl Into<RawString>) {
105 self.trailing = trailing.into();
106 }
107
108 pub fn trailing(&self) -> &RawString {
110 &self.trailing
111 }
112
113 pub fn sort_values(&mut self) {
121 self.items.sort_keys();
123 for value in self.items.values_mut() {
124 match value {
125 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
126 table.sort_values();
127 }
128 _ => {}
129 }
130 }
131 }
132
133 pub fn sort_values_by<F>(&mut self, mut compare: F)
144 where
145 F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering,
146 {
147 self.sort_values_by_internal(&mut compare);
148 }
149
150 fn sort_values_by_internal<F>(&mut self, compare: &mut F)
151 where
152 F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering,
153 {
154 let modified_cmp =
155 |key1: &Key, val1: &Item, key2: &Key, val2: &Item| -> std::cmp::Ordering {
156 match (val1.as_value(), val2.as_value()) {
157 (Some(v1), Some(v2)) => compare(key1, v1, key2, v2),
158 (Some(_), None) => std::cmp::Ordering::Greater,
159 (None, Some(_)) => std::cmp::Ordering::Less,
160 (None, None) => std::cmp::Ordering::Equal,
161 }
162 };
163
164 self.items.sort_by(modified_cmp);
165 for value in self.items.values_mut() {
166 match value {
167 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
168 table.sort_values_by_internal(compare);
169 }
170 _ => {}
171 }
172 }
173 }
174
175 pub(crate) fn set_implicit(&mut self, implicit: bool) {
197 self.implicit = implicit;
198 }
199
200 pub(crate) fn is_implicit(&self) -> bool {
202 self.implicit
203 }
204
205 pub fn set_dotted(&mut self, yes: bool) {
207 self.dotted = yes;
208 }
209
210 pub fn is_dotted(&self) -> bool {
212 self.dotted
213 }
214
215 pub fn decor_mut(&mut self) -> &mut Decor {
217 &mut self.decor
218 }
219
220 pub fn decor(&self) -> &Decor {
222 &self.decor
223 }
224
225 pub fn key(&self, key: &str) -> Option<&'_ Key> {
227 self.items.get_full(key).map(|(_, key, _)| key)
228 }
229
230 pub fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
232 use indexmap::map::MutableKeys;
233 self.items
234 .get_full_mut2(key)
235 .map(|(_, key, _)| key.as_mut())
236 }
237
238 pub fn span(&self) -> Option<std::ops::Range<usize>> {
242 self.span.clone()
243 }
244
245 pub(crate) fn despan(&mut self, input: &str) {
246 use indexmap::map::MutableKeys;
247 self.span = None;
248 self.decor.despan(input);
249 self.trailing.despan(input);
250 for (key, value) in self.items.iter_mut2() {
251 key.despan(input);
252 value.despan(input);
253 }
254 }
255}
256
257impl InlineTable {
258 pub fn iter(&self) -> InlineTableIter<'_> {
260 Box::new(
261 self.items
262 .iter()
263 .filter(|(_, value)| !value.is_none())
264 .map(|(key, value)| (key.get(), value.as_value().unwrap())),
265 )
266 }
267
268 pub fn iter_mut(&mut self) -> InlineTableIterMut<'_> {
270 use indexmap::map::MutableKeys;
271 Box::new(
272 self.items
273 .iter_mut2()
274 .filter(|(_, value)| value.is_value())
275 .map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap())),
276 )
277 }
278
279 pub fn len(&self) -> usize {
281 self.iter().count()
282 }
283
284 pub fn is_empty(&self) -> bool {
286 self.len() == 0
287 }
288
289 pub fn clear(&mut self) {
291 self.items.clear();
292 }
293
294 pub fn entry(&'_ mut self, key: impl Into<String>) -> InlineEntry<'_> {
296 match self.items.entry(key.into().into()) {
297 indexmap::map::Entry::Occupied(mut entry) => {
298 let scratch = std::mem::take(entry.get_mut());
300 let scratch = Item::Value(
301 scratch
302 .into_value()
303 .unwrap_or_else(|_| Value::InlineTable(Default::default())),
306 );
307 *entry.get_mut() = scratch;
308
309 InlineEntry::Occupied(InlineOccupiedEntry { entry })
310 }
311 indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { entry }),
312 }
313 }
314
315 pub fn entry_format<'a>(&'a mut self, key: &Key) -> InlineEntry<'a> {
317 match self.items.entry(key.clone()) {
319 indexmap::map::Entry::Occupied(mut entry) => {
320 let scratch = std::mem::take(entry.get_mut());
322 let scratch = Item::Value(
323 scratch
324 .into_value()
325 .unwrap_or_else(|_| Value::InlineTable(Default::default())),
328 );
329 *entry.get_mut() = scratch;
330
331 InlineEntry::Occupied(InlineOccupiedEntry { entry })
332 }
333 indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { entry }),
334 }
335 }
336 pub fn get(&self, key: &str) -> Option<&Value> {
338 self.items.get(key).and_then(|value| value.as_value())
339 }
340
341 pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
343 self.items
344 .get_mut(key)
345 .and_then(|value| value.as_value_mut())
346 }
347
348 pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
350 self.items.get_full(key).and_then(|(_, key, value)| {
351 if !value.is_none() {
352 Some((key, value))
353 } else {
354 None
355 }
356 })
357 }
358
359 pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
361 use indexmap::map::MutableKeys;
362 self.items.get_full_mut2(key).and_then(|(_, key, value)| {
363 if !value.is_none() {
364 Some((key.as_mut(), value))
365 } else {
366 None
367 }
368 })
369 }
370
371 pub fn contains_key(&self, key: &str) -> bool {
373 if let Some(value) = self.items.get(key) {
374 value.is_value()
375 } else {
376 false
377 }
378 }
379
380 pub fn get_or_insert<V: Into<Value>>(
383 &mut self,
384 key: impl Into<String>,
385 value: V,
386 ) -> &mut Value {
387 let key = key.into();
388 self.items
389 .entry(Key::new(key))
390 .or_insert(Item::Value(value.into()))
391 .as_value_mut()
392 .expect("non-value type in inline table")
393 }
394
395 pub fn insert(&mut self, key: impl Into<String>, value: Value) -> Option<Value> {
397 use indexmap::map::MutableEntryKey;
398 let key = Key::new(key);
399 let value = Item::Value(value);
400 match self.items.entry(key.clone()) {
401 indexmap::map::Entry::Occupied(mut entry) => {
402 entry.key_mut().fmt();
403 let old = std::mem::replace(entry.get_mut(), value);
404 old.into_value().ok()
405 }
406 indexmap::map::Entry::Vacant(entry) => {
407 entry.insert(value);
408 None
409 }
410 }
411 }
412
413 pub fn insert_formatted(&mut self, key: &Key, value: Value) -> Option<Value> {
415 use indexmap::map::MutableEntryKey;
416 let value = Item::Value(value);
417 match self.items.entry(key.clone()) {
418 indexmap::map::Entry::Occupied(mut entry) => {
419 *entry.key_mut() = key.clone();
420 let old = std::mem::replace(entry.get_mut(), value);
421 old.into_value().ok()
422 }
423 indexmap::map::Entry::Vacant(entry) => {
424 entry.insert(value);
425 None
426 }
427 }
428 }
429
430 pub fn remove(&mut self, key: &str) -> Option<Value> {
432 self.items
433 .shift_remove(key)
434 .and_then(|value| value.into_value().ok())
435 }
436
437 pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Value)> {
439 self.items
440 .shift_remove_entry(key)
441 .and_then(|(key, value)| Some((key, value.into_value().ok()?)))
442 }
443
444 pub fn retain<F>(&mut self, mut keep: F)
451 where
452 F: FnMut(&str, &mut Value) -> bool,
453 {
454 self.items.retain(|key, item| {
455 item.as_value_mut()
456 .map(|value| keep(key, value))
457 .unwrap_or(false)
458 });
459 }
460}
461
462#[cfg(feature = "display")]
463impl std::fmt::Display for InlineTable {
464 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
465 crate::encode::encode_table(self, f, None, ("", ""))
466 }
467}
468
469impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for InlineTable {
470 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
471 for (key, value) in iter {
472 let key = key.into();
473 let value = Item::Value(value.into());
474 self.items.insert(key, value);
475 }
476 }
477}
478
479impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for InlineTable {
480 fn from_iter<I>(iter: I) -> Self
481 where
482 I: IntoIterator<Item = (K, V)>,
483 {
484 let mut table = Self::new();
485 table.extend(iter);
486 table
487 }
488}
489
490impl IntoIterator for InlineTable {
491 type Item = (String, Value);
492 type IntoIter = InlineTableIntoIter;
493
494 fn into_iter(self) -> Self::IntoIter {
495 Box::new(
496 self.items
497 .into_iter()
498 .filter(|(_, value)| value.is_value())
499 .map(|(key, value)| (key.into(), value.into_value().unwrap())),
500 )
501 }
502}
503
504impl<'s> IntoIterator for &'s InlineTable {
505 type Item = (&'s str, &'s Value);
506 type IntoIter = InlineTableIter<'s>;
507
508 fn into_iter(self) -> Self::IntoIter {
509 self.iter()
510 }
511}
512
513fn decorate_inline_table(table: &mut InlineTable) {
514 use indexmap::map::MutableKeys;
515 for (mut key, value) in table
516 .items
517 .iter_mut2()
518 .filter(|(_, value)| value.is_value())
519 .map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap()))
520 {
521 key.leaf_decor_mut().clear();
522 key.dotted_decor_mut().clear();
523 value.decor_mut().clear();
524 }
525}
526
527pub type InlineTableIntoIter = Box<dyn Iterator<Item = (String, Value)>>;
529pub type InlineTableIter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Value)> + 'a>;
531pub type InlineTableIterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Value)> + 'a>;
533
534impl TableLike for InlineTable {
535 fn iter(&self) -> Iter<'_> {
536 Box::new(self.items.iter().map(|(key, value)| (key.get(), value)))
537 }
538 fn iter_mut(&mut self) -> IterMut<'_> {
539 use indexmap::map::MutableKeys;
540 Box::new(
541 self.items
542 .iter_mut2()
543 .map(|(key, value)| (key.as_mut(), value)),
544 )
545 }
546 fn clear(&mut self) {
547 self.clear();
548 }
549 fn entry<'a>(&'a mut self, key: &str) -> crate::Entry<'a> {
550 match self.items.entry(key.into()) {
552 indexmap::map::Entry::Occupied(entry) => {
553 crate::Entry::Occupied(crate::OccupiedEntry { entry })
554 }
555 indexmap::map::Entry::Vacant(entry) => {
556 crate::Entry::Vacant(crate::VacantEntry { entry })
557 }
558 }
559 }
560 fn entry_format<'a>(&'a mut self, key: &Key) -> crate::Entry<'a> {
561 match self.items.entry(key.get().into()) {
563 indexmap::map::Entry::Occupied(entry) => {
564 crate::Entry::Occupied(crate::OccupiedEntry { entry })
565 }
566 indexmap::map::Entry::Vacant(entry) => {
567 crate::Entry::Vacant(crate::VacantEntry { entry })
568 }
569 }
570 }
571 fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
572 self.items.get(key)
573 }
574 fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
575 self.items.get_mut(key)
576 }
577 fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
578 self.get_key_value(key)
579 }
580 fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
581 self.get_key_value_mut(key)
582 }
583 fn contains_key(&self, key: &str) -> bool {
584 self.contains_key(key)
585 }
586 fn insert(&mut self, key: &str, value: Item) -> Option<Item> {
587 self.insert(key, value.into_value().unwrap())
588 .map(Item::Value)
589 }
590 fn remove(&mut self, key: &str) -> Option<Item> {
591 self.remove(key).map(Item::Value)
592 }
593
594 fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
595 self.get_values()
596 }
597 fn fmt(&mut self) {
598 self.fmt();
599 }
600 fn sort_values(&mut self) {
601 self.sort_values();
602 }
603 fn set_dotted(&mut self, yes: bool) {
604 self.set_dotted(yes);
605 }
606 fn is_dotted(&self) -> bool {
607 self.is_dotted()
608 }
609
610 fn key(&self, key: &str) -> Option<&'_ Key> {
611 self.key(key)
612 }
613 fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
614 self.key_mut(key)
615 }
616}
617
618pub(crate) const DEFAULT_INLINE_KEY_DECOR: (&str, &str) = (" ", " ");
620
621pub enum InlineEntry<'a> {
623 Occupied(InlineOccupiedEntry<'a>),
625 Vacant(InlineVacantEntry<'a>),
627}
628
629impl<'a> InlineEntry<'a> {
630 pub fn key(&self) -> &str {
642 match self {
643 InlineEntry::Occupied(e) => e.key(),
644 InlineEntry::Vacant(e) => e.key(),
645 }
646 }
647
648 pub fn or_insert(self, default: Value) -> &'a mut Value {
651 match self {
652 InlineEntry::Occupied(entry) => entry.into_mut(),
653 InlineEntry::Vacant(entry) => entry.insert(default),
654 }
655 }
656
657 pub fn or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value {
660 match self {
661 InlineEntry::Occupied(entry) => entry.into_mut(),
662 InlineEntry::Vacant(entry) => entry.insert(default()),
663 }
664 }
665}
666
667pub struct InlineOccupiedEntry<'a> {
669 entry: indexmap::map::OccupiedEntry<'a, Key, Item>,
670}
671
672impl<'a> InlineOccupiedEntry<'a> {
673 pub fn key(&self) -> &str {
685 self.entry.key().get()
686 }
687
688 pub fn key_mut(&mut self) -> KeyMut<'_> {
690 use indexmap::map::MutableEntryKey;
691 self.entry.key_mut().as_mut()
692 }
693
694 pub fn get(&self) -> &Value {
696 self.entry.get().as_value().unwrap()
697 }
698
699 pub fn get_mut(&mut self) -> &mut Value {
701 self.entry.get_mut().as_value_mut().unwrap()
702 }
703
704 pub fn into_mut(self) -> &'a mut Value {
707 self.entry.into_mut().as_value_mut().unwrap()
708 }
709
710 pub fn insert(&mut self, value: Value) -> Value {
712 let value = Item::Value(value);
713 self.entry.insert(value).into_value().unwrap()
714 }
715
716 pub fn remove(self) -> Value {
718 self.entry.shift_remove().into_value().unwrap()
719 }
720}
721
722pub struct InlineVacantEntry<'a> {
724 entry: indexmap::map::VacantEntry<'a, Key, Item>,
725}
726
727impl<'a> InlineVacantEntry<'a> {
728 pub fn key(&self) -> &str {
740 self.entry.key().get()
741 }
742
743 pub fn insert(self, value: Value) -> &'a mut Value {
746 let entry = self.entry;
747 let value = Item::Value(value);
748 entry.insert(value).as_value_mut().unwrap()
749 }
750}