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 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 Item::Table(table) => {
75 table.append_all_values(&path, values);
76 }
77 _ => {}
78 }
79 }
80 }
81
82 pub fn fmt(&mut self) {
84 decorate_inline_table(self);
85 }
86
87 pub fn sort_values(&mut self) {
95 self.items.sort_keys();
97 for value in self.items.values_mut() {
98 match value {
99 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
100 table.sort_values();
101 }
102 _ => {}
103 }
104 }
105 }
106
107 pub fn sort_values_by<F>(&mut self, mut compare: F)
118 where
119 F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering,
120 {
121 self.sort_values_by_internal(&mut compare);
122 }
123
124 fn sort_values_by_internal<F>(&mut self, compare: &mut F)
125 where
126 F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering,
127 {
128 let modified_cmp =
129 |key1: &Key, val1: &Item, key2: &Key, val2: &Item| -> std::cmp::Ordering {
130 match (val1.as_value(), val2.as_value()) {
131 (Some(v1), Some(v2)) => compare(key1, v1, key2, v2),
132 (Some(_), None) => std::cmp::Ordering::Greater,
133 (None, Some(_)) => std::cmp::Ordering::Less,
134 (None, None) => std::cmp::Ordering::Equal,
135 }
136 };
137
138 self.items.sort_by(modified_cmp);
139 for value in self.items.values_mut() {
140 match value {
141 Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
142 table.sort_values_by_internal(compare);
143 }
144 _ => {}
145 }
146 }
147 }
148
149 pub(crate) fn set_implicit(&mut self, implicit: bool) {
171 self.implicit = implicit;
172 }
173
174 pub(crate) fn is_implicit(&self) -> bool {
176 self.implicit
177 }
178
179 pub fn set_dotted(&mut self, yes: bool) {
181 self.dotted = yes;
182 }
183
184 pub fn is_dotted(&self) -> bool {
186 self.dotted
187 }
188
189 pub fn decor_mut(&mut self) -> &mut Decor {
191 &mut self.decor
192 }
193
194 pub fn decor(&self) -> &Decor {
196 &self.decor
197 }
198
199 pub fn key(&self, key: &str) -> Option<&'_ Key> {
201 self.items.get_full(key).map(|(_, key, _)| key)
202 }
203
204 pub fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
206 use indexmap::map::MutableKeys;
207 self.items
208 .get_full_mut2(key)
209 .map(|(_, key, _)| key.as_mut())
210 }
211
212 pub fn set_preamble(&mut self, preamble: impl Into<RawString>) {
214 self.preamble = preamble.into();
215 }
216
217 pub fn preamble(&self) -> &RawString {
219 &self.preamble
220 }
221
222 pub fn span(&self) -> Option<std::ops::Range<usize>> {
226 self.span.clone()
227 }
228
229 pub(crate) fn despan(&mut self, input: &str) {
230 use indexmap::map::MutableKeys;
231 self.span = None;
232 self.decor.despan(input);
233 self.preamble.despan(input);
234 for (key, value) in self.items.iter_mut2() {
235 key.despan(input);
236 value.despan(input);
237 }
238 }
239}
240
241impl InlineTable {
242 pub fn iter(&self) -> InlineTableIter<'_> {
244 Box::new(
245 self.items
246 .iter()
247 .filter(|(_, value)| !value.is_none())
248 .map(|(key, value)| (key.get(), value.as_value().unwrap())),
249 )
250 }
251
252 pub fn iter_mut(&mut self) -> InlineTableIterMut<'_> {
254 use indexmap::map::MutableKeys;
255 Box::new(
256 self.items
257 .iter_mut2()
258 .filter(|(_, value)| value.is_value())
259 .map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap())),
260 )
261 }
262
263 pub fn len(&self) -> usize {
265 self.iter().count()
266 }
267
268 pub fn is_empty(&self) -> bool {
270 self.len() == 0
271 }
272
273 pub fn clear(&mut self) {
275 self.items.clear();
276 }
277
278 pub fn entry(&'_ mut self, key: impl Into<String>) -> InlineEntry<'_> {
280 match self.items.entry(key.into().into()) {
281 indexmap::map::Entry::Occupied(mut entry) => {
282 let scratch = std::mem::take(entry.get_mut());
284 let scratch = Item::Value(
285 scratch
286 .into_value()
287 .unwrap_or_else(|_| Value::InlineTable(Default::default())),
290 );
291 *entry.get_mut() = scratch;
292
293 InlineEntry::Occupied(InlineOccupiedEntry { entry })
294 }
295 indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { entry }),
296 }
297 }
298
299 pub fn entry_format<'a>(&'a mut self, key: &Key) -> InlineEntry<'a> {
301 match self.items.entry(key.clone()) {
303 indexmap::map::Entry::Occupied(mut entry) => {
304 let scratch = std::mem::take(entry.get_mut());
306 let scratch = Item::Value(
307 scratch
308 .into_value()
309 .unwrap_or_else(|_| Value::InlineTable(Default::default())),
312 );
313 *entry.get_mut() = scratch;
314
315 InlineEntry::Occupied(InlineOccupiedEntry { entry })
316 }
317 indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { entry }),
318 }
319 }
320 pub fn get(&self, key: &str) -> Option<&Value> {
322 self.items.get(key).and_then(|value| value.as_value())
323 }
324
325 pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
327 self.items
328 .get_mut(key)
329 .and_then(|value| value.as_value_mut())
330 }
331
332 pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
334 self.items.get_full(key).and_then(|(_, key, value)| {
335 if !value.is_none() {
336 Some((key, value))
337 } else {
338 None
339 }
340 })
341 }
342
343 pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
345 use indexmap::map::MutableKeys;
346 self.items.get_full_mut2(key).and_then(|(_, key, value)| {
347 if !value.is_none() {
348 Some((key.as_mut(), value))
349 } else {
350 None
351 }
352 })
353 }
354
355 pub fn contains_key(&self, key: &str) -> bool {
357 if let Some(value) = self.items.get(key) {
358 value.is_value()
359 } else {
360 false
361 }
362 }
363
364 pub fn get_or_insert<V: Into<Value>>(
367 &mut self,
368 key: impl Into<String>,
369 value: V,
370 ) -> &mut Value {
371 let key = key.into();
372 self.items
373 .entry(Key::new(key))
374 .or_insert(Item::Value(value.into()))
375 .as_value_mut()
376 .expect("non-value type in inline table")
377 }
378
379 pub fn insert(&mut self, key: impl Into<String>, value: Value) -> Option<Value> {
381 use indexmap::map::MutableEntryKey;
382 let key = Key::new(key);
383 let value = Item::Value(value);
384 match self.items.entry(key.clone()) {
385 indexmap::map::Entry::Occupied(mut entry) => {
386 entry.key_mut().fmt();
387 let old = std::mem::replace(entry.get_mut(), value);
388 old.into_value().ok()
389 }
390 indexmap::map::Entry::Vacant(entry) => {
391 entry.insert(value);
392 None
393 }
394 }
395 }
396
397 pub fn insert_formatted(&mut self, key: &Key, value: Value) -> Option<Value> {
399 use indexmap::map::MutableEntryKey;
400 let value = Item::Value(value);
401 match self.items.entry(key.clone()) {
402 indexmap::map::Entry::Occupied(mut entry) => {
403 *entry.key_mut() = key.clone();
404 let old = std::mem::replace(entry.get_mut(), value);
405 old.into_value().ok()
406 }
407 indexmap::map::Entry::Vacant(entry) => {
408 entry.insert(value);
409 None
410 }
411 }
412 }
413
414 pub fn remove(&mut self, key: &str) -> Option<Value> {
416 self.items
417 .shift_remove(key)
418 .and_then(|value| value.into_value().ok())
419 }
420
421 pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Value)> {
423 self.items
424 .shift_remove_entry(key)
425 .and_then(|(key, value)| Some((key, value.into_value().ok()?)))
426 }
427
428 pub fn retain<F>(&mut self, mut keep: F)
435 where
436 F: FnMut(&str, &mut Value) -> bool,
437 {
438 self.items.retain(|key, item| {
439 item.as_value_mut()
440 .map(|value| keep(key, value))
441 .unwrap_or(false)
442 });
443 }
444}
445
446#[cfg(feature = "display")]
447impl std::fmt::Display for InlineTable {
448 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
449 crate::encode::encode_table(self, f, None, ("", ""))
450 }
451}
452
453impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for InlineTable {
454 fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
455 for (key, value) in iter {
456 let key = key.into();
457 let value = Item::Value(value.into());
458 self.items.insert(key, value);
459 }
460 }
461}
462
463impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for InlineTable {
464 fn from_iter<I>(iter: I) -> Self
465 where
466 I: IntoIterator<Item = (K, V)>,
467 {
468 let mut table = Self::new();
469 table.extend(iter);
470 table
471 }
472}
473
474impl IntoIterator for InlineTable {
475 type Item = (String, Value);
476 type IntoIter = InlineTableIntoIter;
477
478 fn into_iter(self) -> Self::IntoIter {
479 Box::new(
480 self.items
481 .into_iter()
482 .filter(|(_, value)| value.is_value())
483 .map(|(key, value)| (key.into(), value.into_value().unwrap())),
484 )
485 }
486}
487
488impl<'s> IntoIterator for &'s InlineTable {
489 type Item = (&'s str, &'s Value);
490 type IntoIter = InlineTableIter<'s>;
491
492 fn into_iter(self) -> Self::IntoIter {
493 self.iter()
494 }
495}
496
497fn decorate_inline_table(table: &mut InlineTable) {
498 use indexmap::map::MutableKeys;
499 for (mut key, value) in table
500 .items
501 .iter_mut2()
502 .filter(|(_, value)| value.is_value())
503 .map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap()))
504 {
505 key.leaf_decor_mut().clear();
506 key.dotted_decor_mut().clear();
507 value.decor_mut().clear();
508 }
509}
510
511pub type InlineTableIntoIter = Box<dyn Iterator<Item = (String, Value)>>;
513pub type InlineTableIter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Value)> + 'a>;
515pub type InlineTableIterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Value)> + 'a>;
517
518impl TableLike for InlineTable {
519 fn iter(&self) -> Iter<'_> {
520 Box::new(self.items.iter().map(|(key, value)| (key.get(), value)))
521 }
522 fn iter_mut(&mut self) -> IterMut<'_> {
523 use indexmap::map::MutableKeys;
524 Box::new(
525 self.items
526 .iter_mut2()
527 .map(|(key, value)| (key.as_mut(), value)),
528 )
529 }
530 fn clear(&mut self) {
531 self.clear();
532 }
533 fn entry<'a>(&'a mut self, key: &str) -> crate::Entry<'a> {
534 match self.items.entry(key.into()) {
536 indexmap::map::Entry::Occupied(entry) => {
537 crate::Entry::Occupied(crate::OccupiedEntry { entry })
538 }
539 indexmap::map::Entry::Vacant(entry) => {
540 crate::Entry::Vacant(crate::VacantEntry { entry })
541 }
542 }
543 }
544 fn entry_format<'a>(&'a mut self, key: &Key) -> crate::Entry<'a> {
545 match self.items.entry(key.get().into()) {
547 indexmap::map::Entry::Occupied(entry) => {
548 crate::Entry::Occupied(crate::OccupiedEntry { entry })
549 }
550 indexmap::map::Entry::Vacant(entry) => {
551 crate::Entry::Vacant(crate::VacantEntry { entry })
552 }
553 }
554 }
555 fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
556 self.items.get(key)
557 }
558 fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
559 self.items.get_mut(key)
560 }
561 fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
562 self.get_key_value(key)
563 }
564 fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
565 self.get_key_value_mut(key)
566 }
567 fn contains_key(&self, key: &str) -> bool {
568 self.contains_key(key)
569 }
570 fn insert(&mut self, key: &str, value: Item) -> Option<Item> {
571 self.insert(key, value.into_value().unwrap())
572 .map(Item::Value)
573 }
574 fn remove(&mut self, key: &str) -> Option<Item> {
575 self.remove(key).map(Item::Value)
576 }
577
578 fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
579 self.get_values()
580 }
581 fn fmt(&mut self) {
582 self.fmt();
583 }
584 fn sort_values(&mut self) {
585 self.sort_values();
586 }
587 fn set_dotted(&mut self, yes: bool) {
588 self.set_dotted(yes);
589 }
590 fn is_dotted(&self) -> bool {
591 self.is_dotted()
592 }
593
594 fn key(&self, key: &str) -> Option<&'_ Key> {
595 self.key(key)
596 }
597 fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
598 self.key_mut(key)
599 }
600}
601
602pub(crate) const DEFAULT_INLINE_KEY_DECOR: (&str, &str) = (" ", " ");
604
605pub enum InlineEntry<'a> {
607 Occupied(InlineOccupiedEntry<'a>),
609 Vacant(InlineVacantEntry<'a>),
611}
612
613impl<'a> InlineEntry<'a> {
614 pub fn key(&self) -> &str {
626 match self {
627 InlineEntry::Occupied(e) => e.key(),
628 InlineEntry::Vacant(e) => e.key(),
629 }
630 }
631
632 pub fn or_insert(self, default: Value) -> &'a mut Value {
635 match self {
636 InlineEntry::Occupied(entry) => entry.into_mut(),
637 InlineEntry::Vacant(entry) => entry.insert(default),
638 }
639 }
640
641 pub fn or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value {
644 match self {
645 InlineEntry::Occupied(entry) => entry.into_mut(),
646 InlineEntry::Vacant(entry) => entry.insert(default()),
647 }
648 }
649}
650
651pub struct InlineOccupiedEntry<'a> {
653 entry: indexmap::map::OccupiedEntry<'a, Key, Item>,
654}
655
656impl<'a> InlineOccupiedEntry<'a> {
657 pub fn key(&self) -> &str {
669 self.entry.key().get()
670 }
671
672 pub fn key_mut(&mut self) -> KeyMut<'_> {
674 use indexmap::map::MutableEntryKey;
675 self.entry.key_mut().as_mut()
676 }
677
678 pub fn get(&self) -> &Value {
680 self.entry.get().as_value().unwrap()
681 }
682
683 pub fn get_mut(&mut self) -> &mut Value {
685 self.entry.get_mut().as_value_mut().unwrap()
686 }
687
688 pub fn into_mut(self) -> &'a mut Value {
691 self.entry.into_mut().as_value_mut().unwrap()
692 }
693
694 pub fn insert(&mut self, value: Value) -> Value {
696 let value = Item::Value(value);
697 self.entry.insert(value).into_value().unwrap()
698 }
699
700 pub fn remove(self) -> Value {
702 self.entry.shift_remove().into_value().unwrap()
703 }
704}
705
706pub struct InlineVacantEntry<'a> {
708 entry: indexmap::map::VacantEntry<'a, Key, Item>,
709}
710
711impl<'a> InlineVacantEntry<'a> {
712 pub fn key(&self) -> &str {
724 self.entry.key().get()
725 }
726
727 pub fn insert(self, value: Value) -> &'a mut Value {
730 let entry = self.entry;
731 let value = Item::Value(value);
732 entry.insert(value).as_value_mut().unwrap()
733 }
734}