1use crate::spanned::Spanned;
2use crate::value::Value;
3use indexmap::IndexMap;
4use std::cmp::Ordering;
5
6struct Key<'a>(&'a Spanned<Value>);
7impl std::fmt::Debug for Key<'_> {
8 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9 match self.0.as_ref() {
10 Value::Null => write!(f, "NULL"),
11 Value::Bool(boolean) => write!(f, "{boolean}"),
12 Value::String(value) => write!(f, "{value:?}"),
13 Value::Number(number) => write!(f, "{number}"),
14 Value::Sequence(sequence) => f.debug_list().entries(sequence).finish(),
15 Value::Mapping(mapping) => std::fmt::Display::fmt(mapping, f),
16 Value::Tagged(tagged) => std::fmt::Display::fmt(tagged, f),
17 }
18 }
19}
20
21#[derive(Debug, Clone, Default, Eq, PartialEq)]
22pub struct Mapping(pub IndexMap<Spanned<Value>, Spanned<Value>>);
23
24impl std::fmt::Display for Mapping {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 f.debug_map()
27 .entries(self.0.iter().map(|(k, v)| (Key(k), crate::fmt::Display(v))))
28 .finish()
29 }
30}
31
32pub struct StringValueRepr<'a>(&'a Mapping);
33
34impl std::fmt::Debug for StringValueRepr<'_> {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 std::fmt::Display::fmt(&self, f)
37 }
38}
39
40impl std::fmt::Display for StringValueRepr<'_> {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 f.debug_map()
43 .entries(self.0.iter().map(|(k, v)| (Key(k), v.string_value_repr())))
44 .finish()
45 }
46}
47
48impl Mapping {
49 #[must_use]
50 pub fn string_value_repr(&self) -> StringValueRepr<'_> {
51 StringValueRepr(self)
52 }
53
54 }
58
59impl AsMut<IndexMap<Spanned<Value>, Spanned<Value>>> for Mapping {
60 fn as_mut(&mut self) -> &mut IndexMap<Spanned<Value>, Spanned<Value>> {
61 &mut self.0
62 }
63}
64
65impl AsRef<IndexMap<Spanned<Value>, Spanned<Value>>> for Mapping {
66 fn as_ref(&self) -> &IndexMap<Spanned<Value>, Spanned<Value>> {
67 &self.0
68 }
69}
70
71impl Mapping {
72 #[inline]
74 #[must_use]
75 pub fn new() -> Self {
76 Self::default()
77 }
78
79 #[inline]
81 #[must_use]
82 pub fn with_capacity(capacity: usize) -> Self {
83 Self(IndexMap::with_capacity(capacity))
84 }
85
86 #[inline]
94 pub fn reserve(&mut self, additional: usize) {
95 self.0.reserve(additional);
96 }
97
98 #[inline]
102 pub fn shrink_to_fit(&mut self) {
103 self.0.shrink_to_fit();
104 }
105
106 #[inline]
109 pub fn insert(&mut self, k: Spanned<Value>, v: Spanned<Value>) -> Option<Spanned<Value>> {
110 self.0.insert(k, v)
111 }
112
113 #[inline]
115 pub fn contains_key<I: Index>(&self, index: I) -> bool {
116 index.is_key_into(self)
117 }
118
119 #[inline]
121 pub fn get<I: Index>(&self, index: I) -> Option<&Spanned<Value>> {
122 index.index_into(self)
123 }
124
125 #[inline]
127 pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Spanned<Value>> {
128 index.index_into_mut(self)
129 }
130
131 #[inline]
134 pub fn entry(&mut self, k: Spanned<Value>) -> Entry<'_> {
135 match self.0.entry(k) {
136 indexmap::map::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
137 indexmap::map::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
138 }
139 }
140
141 #[inline]
148 pub fn remove<I: Index>(&mut self, index: I) -> Option<Spanned<Value>> {
149 self.swap_remove(index)
150 }
151
152 #[inline]
159 pub fn remove_entry<I: Index>(&mut self, index: I) -> Option<(Spanned<Value>, Spanned<Value>)> {
160 self.swap_remove_entry(index)
161 }
162
163 #[inline]
169 pub fn swap_remove<I: Index>(&mut self, index: I) -> Option<Spanned<Value>> {
170 index.swap_remove_from(self)
171 }
172
173 #[inline]
179 pub fn swap_remove_entry<I: Index>(
180 &mut self,
181 index: I,
182 ) -> Option<(Spanned<Value>, Spanned<Value>)> {
183 index.swap_remove_entry_from(self)
184 }
185
186 #[inline]
192 pub fn shift_remove<I: Index>(&mut self, index: I) -> Option<Spanned<Value>> {
193 index.shift_remove_from(self)
194 }
195
196 #[inline]
202 pub fn shift_remove_entry<I: Index>(
203 &mut self,
204 index: I,
205 ) -> Option<(Spanned<Value>, Spanned<Value>)> {
206 index.shift_remove_entry_from(self)
207 }
208
209 #[inline]
212 pub fn retain<F>(&mut self, keep: F)
213 where
214 F: FnMut(&Spanned<Value>, &mut Spanned<Value>) -> bool,
215 {
216 self.0.retain(keep);
217 }
218
219 #[inline]
222 #[must_use]
223 pub fn capacity(&self) -> usize {
224 self.0.capacity()
225 }
226
227 #[inline]
229 #[must_use]
230 pub fn len(&self) -> usize {
231 self.0.len()
232 }
233
234 #[inline]
236 #[must_use]
237 pub fn is_empty(&self) -> bool {
238 self.0.is_empty()
239 }
240
241 #[inline]
243 pub fn clear(&mut self) {
244 self.0.clear();
245 }
246
247 #[inline]
250 #[must_use]
251 pub fn iter(&self) -> Iter<'_> {
252 Iter {
253 iter: self.0.iter(),
254 }
255 }
256
257 #[inline]
260 pub fn iter_mut(&mut self) -> IterMut<'_> {
261 IterMut {
262 iter: self.0.iter_mut(),
263 }
264 }
265
266 #[must_use]
268 pub fn keys(&self) -> Keys<'_> {
269 Keys {
270 iter: self.0.keys(),
271 }
272 }
273
274 #[must_use]
276 pub fn into_keys(self) -> IntoKeys {
277 IntoKeys {
278 iter: self.0.into_keys(),
279 }
280 }
281
282 #[must_use]
284 pub fn values(&self) -> Values<'_> {
285 Values {
286 iter: self.0.values(),
287 }
288 }
289
290 pub fn values_mut(&mut self) -> ValuesMut<'_> {
292 ValuesMut {
293 iter: self.0.values_mut(),
294 }
295 }
296
297 #[must_use]
299 pub fn into_values(self) -> IntoValues {
300 IntoValues {
301 iter: self.0.into_values(),
302 }
303 }
304}
305
306pub trait Index: crate::private::Sealed {
311 #[doc(hidden)]
312 fn is_key_into(&self, v: &Mapping) -> bool;
313
314 #[doc(hidden)]
315 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Spanned<Value>>;
316
317 #[doc(hidden)]
318 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Spanned<Value>>;
319
320 #[doc(hidden)]
321 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>>;
322
323 #[doc(hidden)]
324 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)>;
325
326 #[doc(hidden)]
327 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>>;
328
329 #[doc(hidden)]
330 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)>;
331}
332
333struct HashLikeValue<'a>(&'a str);
334
335impl indexmap::Equivalent<Spanned<Value>> for HashLikeValue<'_> {
336 fn equivalent(&self, key: &Spanned<Value>) -> bool {
337 match key.as_ref() {
338 Value::String(string) => self.0 == string,
339 _ => false,
340 }
341 }
342}
343
344impl indexmap::Equivalent<Value> for HashLikeValue<'_> {
345 fn equivalent(&self, key: &Value) -> bool {
346 match key {
347 Value::String(string) => self.0 == string,
348 _ => false,
349 }
350 }
351}
352
353impl std::hash::Hash for HashLikeValue<'_> {
355 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
356 const STRING: Value = Value::String(String::new());
357 std::mem::discriminant(&STRING).hash(state);
358 self.0.hash(state);
359 }
360}
361
362impl Index for Spanned<Value> {
363 fn is_key_into(&self, v: &Mapping) -> bool {
364 v.0.contains_key(self)
365 }
366 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Spanned<Value>> {
367 v.0.get(self)
368 }
369 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Spanned<Value>> {
370 v.0.get_mut(self)
371 }
372 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>> {
373 v.0.swap_remove(self)
374 }
375 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)> {
376 v.0.swap_remove_entry(self)
377 }
378 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>> {
379 v.0.shift_remove(self)
380 }
381 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)> {
382 v.0.shift_remove_entry(self)
383 }
384}
385
386impl Index for Value {
387 fn is_key_into(&self, v: &Mapping) -> bool {
388 v.0.contains_key(self)
389 }
390 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Spanned<Value>> {
391 v.0.get(self)
392 }
393 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Spanned<Value>> {
394 v.0.get_mut(self)
395 }
396 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>> {
397 v.0.swap_remove(self)
398 }
399 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)> {
400 v.0.swap_remove_entry(self)
401 }
402 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>> {
403 v.0.shift_remove(self)
404 }
405 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)> {
406 v.0.shift_remove_entry(self)
407 }
408}
409
410impl Index for str {
411 fn is_key_into(&self, v: &Mapping) -> bool {
412 v.0.contains_key(&HashLikeValue(self))
413 }
414 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Spanned<Value>> {
415 v.0.get(&HashLikeValue(self))
416 }
417 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Spanned<Value>> {
418 v.0.get_mut(&HashLikeValue(self))
419 }
420 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>> {
421 v.0.swap_remove(&HashLikeValue(self))
422 }
423 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)> {
424 v.0.swap_remove_entry(&HashLikeValue(self))
425 }
426 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>> {
427 v.0.shift_remove(&HashLikeValue(self))
428 }
429 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)> {
430 v.0.shift_remove_entry(&HashLikeValue(self))
431 }
432}
433
434impl Index for String {
435 fn is_key_into(&self, v: &Mapping) -> bool {
436 self.as_str().is_key_into(v)
437 }
438 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Spanned<Value>> {
439 self.as_str().index_into(v)
440 }
441 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Spanned<Value>> {
442 self.as_str().index_into_mut(v)
443 }
444 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>> {
445 self.as_str().swap_remove_from(v)
446 }
447 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)> {
448 self.as_str().swap_remove_entry_from(v)
449 }
450 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>> {
451 self.as_str().shift_remove_from(v)
452 }
453 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)> {
454 self.as_str().shift_remove_entry_from(v)
455 }
456}
457
458impl<T> Index for &T
459where
460 T: ?Sized + Index,
461{
462 fn is_key_into(&self, v: &Mapping) -> bool {
463 (**self).is_key_into(v)
464 }
465 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Spanned<Value>> {
466 (**self).index_into(v)
467 }
468 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Spanned<Value>> {
469 (**self).index_into_mut(v)
470 }
471 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>> {
472 (**self).swap_remove_from(v)
473 }
474 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)> {
475 (**self).swap_remove_entry_from(v)
476 }
477 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Spanned<Value>> {
478 (**self).shift_remove_from(v)
479 }
480 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Spanned<Value>, Spanned<Value>)> {
481 (**self).shift_remove_entry_from(v)
482 }
483}
484
485#[allow(clippy::derived_hash_with_manual_eq)]
486impl std::hash::Hash for Mapping {
487 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
488 use std::hash::Hasher;
489 let mut xor = 0;
491 for (k, v) in &self.0 {
492 let mut hasher = std::collections::hash_map::DefaultHasher::new();
493 k.hash(&mut hasher);
494 v.hash(&mut hasher);
495 xor ^= hasher.finish();
496 }
497 xor.hash(state);
498 }
499}
500
501impl PartialOrd for Mapping {
502 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
503 let mut self_entries = Vec::from_iter(self);
504 let mut other_entries = Vec::from_iter(other);
505
506 fn total_cmp(a: &Value, b: &Value) -> Ordering {
509 match (a, b) {
510 (Value::Null, Value::Null) => Ordering::Equal,
511 (Value::Null, _) => Ordering::Less,
512 (_, Value::Null) => Ordering::Greater,
513
514 (Value::Bool(a), Value::Bool(b)) => a.cmp(b),
515 (Value::Bool(_), _) => Ordering::Less,
516 (_, Value::Bool(_)) => Ordering::Greater,
517
518 (Value::Number(a), Value::Number(b)) => a.total_cmp(b),
519 (Value::Number(_), _) => Ordering::Less,
520 (_, Value::Number(_)) => Ordering::Greater,
521
522 (Value::String(a), Value::String(b)) => a.cmp(b),
523 (Value::String(_), _) => Ordering::Less,
524 (_, Value::String(_)) => Ordering::Greater,
525
526 (Value::Sequence(a), Value::Sequence(b)) => {
527 iter_cmp_by(a, b, |a, b| total_cmp(a.as_ref(), b.as_ref()))
528 }
529 (Value::Sequence(_), _) => Ordering::Less,
530 (_, Value::Sequence(_)) => Ordering::Greater,
531
532 (Value::Mapping(a), Value::Mapping(b)) => {
533 iter_cmp_by(a, b, |(ak, av), (bk, bv)| {
534 total_cmp(ak.as_ref(), bk.as_ref())
535 .then_with(|| total_cmp(av.as_ref(), bv.as_ref()))
536 })
537 }
538 (Value::Mapping(_), _) => Ordering::Less,
539 (_, Value::Mapping(_)) => Ordering::Greater,
540
541 (Value::Tagged(a), Value::Tagged(b)) => a
542 .tag
543 .cmp(&b.tag)
544 .then_with(|| total_cmp(a.value.as_ref(), b.value.as_ref())),
545 }
546 }
547
548 fn iter_cmp_by<I, F>(this: I, other: I, mut cmp: F) -> Ordering
549 where
550 I: IntoIterator,
551 F: FnMut(I::Item, I::Item) -> Ordering,
552 {
553 let mut this = this.into_iter();
554 let mut other = other.into_iter();
555
556 loop {
557 let x = match this.next() {
558 None => {
559 if other.next().is_none() {
560 return Ordering::Equal;
561 }
562 return Ordering::Less;
563 }
564 Some(val) => val,
565 };
566
567 let y = match other.next() {
568 None => return Ordering::Greater,
569 Some(val) => val,
570 };
571
572 match cmp(x, y) {
573 Ordering::Equal => {}
574 non_eq => return non_eq,
575 }
576 }
577 }
578
579 let total_cmp = |&(a, _): &(&Spanned<Value>, &Spanned<Value>),
583 &(b, _): &(&Spanned<Value>, &Spanned<Value>)| {
584 total_cmp(a.as_ref(), b.as_ref())
585 };
586 self_entries.sort_by(total_cmp);
587 other_entries.sort_by(total_cmp);
588 self_entries.partial_cmp(&other_entries)
589 }
590}
591
592impl<I> std::ops::Index<I> for Mapping
593where
594 I: Index,
595{
596 type Output = Spanned<Value>;
597
598 #[inline]
599 #[track_caller]
600 fn index(&self, index: I) -> &Self::Output {
601 index.index_into(self).unwrap()
602 }
603}
604
605impl<I> std::ops::IndexMut<I> for Mapping
606where
607 I: Index,
608{
609 #[inline]
610 #[track_caller]
611 fn index_mut(&mut self, index: I) -> &mut Spanned<Value> {
612 index.index_into_mut(self).unwrap()
613 }
614}
615
616impl Extend<(Spanned<Value>, Spanned<Value>)> for Mapping {
617 #[inline]
618 fn extend<I: IntoIterator<Item = (Spanned<Value>, Spanned<Value>)>>(&mut self, iter: I) {
619 self.0.extend(iter);
620 }
621}
622
623impl FromIterator<(Spanned<Value>, Spanned<Value>)> for Mapping {
624 #[inline]
625 fn from_iter<I: IntoIterator<Item = (Spanned<Value>, Spanned<Value>)>>(iter: I) -> Self {
626 Mapping(IndexMap::from_iter(iter))
627 }
628}
629
630macro_rules! delegate_iterator {
631 (($name:ident $($generics:tt)*) => $item:ty) => {
632 impl $($generics)* Iterator for $name $($generics)* {
633 type Item = $item;
634 #[inline]
635 fn next(&mut self) -> Option<Self::Item> {
636 self.iter.next()
637 }
638 #[inline]
639 fn size_hint(&self) -> (usize, Option<usize>) {
640 self.iter.size_hint()
641 }
642 }
643
644 impl $($generics)* ExactSizeIterator for $name $($generics)* {
645 #[inline]
646 fn len(&self) -> usize {
647 self.iter.len()
648 }
649 }
650 }
651}
652
653pub struct Iter<'a> {
655 iter: indexmap::map::Iter<'a, Spanned<Value>, Spanned<Value>>,
656}
657
658delegate_iterator!((Iter<'a>) => (&'a Spanned<Value>, &'a Spanned<Value>));
659
660impl<'a> IntoIterator for &'a Mapping {
661 type Item = (&'a Spanned<Value>, &'a Spanned<Value>);
662 type IntoIter = Iter<'a>;
663 #[inline]
664 fn into_iter(self) -> Self::IntoIter {
665 Iter {
666 iter: self.0.iter(),
667 }
668 }
669}
670
671pub struct IterMut<'a> {
673 iter: indexmap::map::IterMut<'a, Spanned<Value>, Spanned<Value>>,
674}
675
676delegate_iterator!((IterMut<'a>) => (&'a Spanned<Value>, &'a mut Spanned<Value>));
677
678impl<'a> IntoIterator for &'a mut Mapping {
679 type Item = (&'a Spanned<Value>, &'a mut Spanned<Value>);
680 type IntoIter = IterMut<'a>;
681 #[inline]
682 fn into_iter(self) -> Self::IntoIter {
683 IterMut {
684 iter: self.0.iter_mut(),
685 }
686 }
687}
688
689pub struct IntoIter {
691 iter: indexmap::map::IntoIter<Spanned<Value>, Spanned<Value>>,
692}
693
694delegate_iterator!((IntoIter) => (Spanned<Value>, Spanned<Value>));
695
696impl IntoIterator for Mapping {
697 type Item = (Spanned<Value>, Spanned<Value>);
698 type IntoIter = IntoIter;
699 #[inline]
700 fn into_iter(self) -> Self::IntoIter {
701 IntoIter {
702 iter: self.0.into_iter(),
703 }
704 }
705}
706
707pub struct Keys<'a> {
709 iter: indexmap::map::Keys<'a, Spanned<Value>, Spanned<Value>>,
710}
711
712delegate_iterator!((Keys<'a>) => &'a Spanned<Value>);
713
714pub struct IntoKeys {
716 iter: indexmap::map::IntoKeys<Spanned<Value>, Spanned<Value>>,
717}
718
719delegate_iterator!((IntoKeys) => Spanned<Value>);
720
721pub struct Values<'a> {
723 iter: indexmap::map::Values<'a, Spanned<Value>, Spanned<Value>>,
724}
725
726delegate_iterator!((Values<'a>) => &'a Spanned<Value>);
727
728pub struct ValuesMut<'a> {
730 iter: indexmap::map::ValuesMut<'a, Spanned<Value>, Spanned<Value>>,
731}
732
733delegate_iterator!((ValuesMut<'a>) => &'a mut Spanned<Value>);
734
735pub struct IntoValues {
737 iter: indexmap::map::IntoValues<Spanned<Value>, Spanned<Value>>,
738}
739
740delegate_iterator!((IntoValues) => Spanned<Value>);
741
742pub enum Entry<'a> {
744 Occupied(OccupiedEntry<'a>),
746 Vacant(VacantEntry<'a>),
748}
749
750pub struct OccupiedEntry<'a> {
753 occupied: indexmap::map::OccupiedEntry<'a, Spanned<Value>, Spanned<Value>>,
754}
755
756pub struct VacantEntry<'a> {
759 vacant: indexmap::map::VacantEntry<'a, Spanned<Value>, Spanned<Value>>,
760}
761
762impl<'a> Entry<'a> {
763 #[must_use]
765 pub fn key(&self) -> &Spanned<Value> {
766 match self {
767 Entry::Vacant(e) => e.key(),
768 Entry::Occupied(e) => e.key(),
769 }
770 }
771
772 #[must_use]
775 pub fn or_insert(self, default: Spanned<Value>) -> &'a mut Spanned<Value> {
776 match self {
777 Entry::Vacant(entry) => entry.insert(default),
778 Entry::Occupied(entry) => entry.into_mut(),
779 }
780 }
781
782 pub fn or_insert_with<F>(self, default: F) -> &'a mut Spanned<Value>
786 where
787 F: FnOnce() -> Spanned<Value>,
788 {
789 match self {
790 Entry::Vacant(entry) => entry.insert(default()),
791 Entry::Occupied(entry) => entry.into_mut(),
792 }
793 }
794
795 pub fn and_modify<F>(self, f: F) -> Self
798 where
799 F: FnOnce(&mut Spanned<Value>),
800 {
801 match self {
802 Entry::Occupied(mut entry) => {
803 f(entry.get_mut());
804 Entry::Occupied(entry)
805 }
806 Entry::Vacant(entry) => Entry::Vacant(entry),
807 }
808 }
809}
810
811impl<'a> OccupiedEntry<'a> {
812 #[inline]
814 #[must_use]
815 pub fn key(&self) -> &Spanned<Value> {
816 self.occupied.key()
817 }
818
819 #[inline]
821 #[must_use]
822 pub fn get(&self) -> &Spanned<Value> {
823 self.occupied.get()
824 }
825
826 #[inline]
828 pub fn get_mut(&mut self) -> &mut Spanned<Value> {
829 self.occupied.get_mut()
830 }
831
832 #[inline]
834 #[must_use]
835 pub fn into_mut(self) -> &'a mut Spanned<Value> {
836 self.occupied.into_mut()
837 }
838
839 #[inline]
842 pub fn insert(&mut self, value: Spanned<Value>) -> Spanned<Value> {
843 self.occupied.insert(value)
844 }
845
846 #[inline]
848 #[must_use]
849 pub fn remove(self) -> Spanned<Value> {
850 self.occupied.swap_remove()
851 }
852
853 #[inline]
855 #[must_use]
856 pub fn remove_entry(self) -> (Spanned<Value>, Spanned<Value>) {
857 self.occupied.swap_remove_entry()
858 }
859}
860
861impl<'a> VacantEntry<'a> {
862 #[inline]
865 #[must_use]
866 pub fn key(&self) -> &Spanned<Value> {
867 self.vacant.key()
868 }
869
870 #[inline]
872 #[must_use]
873 pub fn into_key(self) -> Spanned<Value> {
874 self.vacant.into_key()
875 }
876
877 #[inline]
880 #[must_use]
881 pub fn insert(self, value: Spanned<Value>) -> &'a mut Spanned<Value> {
882 self.vacant.insert(value)
883 }
884}
885
886#[cfg(feature = "serde")]
887impl serde::Serialize for Mapping {
888 #[inline]
889 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
890 use serde::ser::SerializeMap;
891 let mut map_serializer = serializer.serialize_map(Some(self.len()))?;
892 for (k, v) in self {
893 map_serializer.serialize_entry(k, v)?;
894 }
895 map_serializer.end()
896 }
897}
898
899#[cfg(feature = "serde")]
900impl<'de> serde::Deserialize<'de> for Mapping {
901 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
902 where
903 D: serde::Deserializer<'de>,
904 {
905 struct Visitor;
906
907 impl<'de> serde::de::Visitor<'de> for Visitor {
908 type Value = Mapping;
909
910 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
911 formatter.write_str("a YAML mapping")
912 }
913
914 #[inline]
915 fn visit_unit<E>(self) -> Result<Self::Value, E>
916 where
917 E: serde::de::Error,
918 {
919 Ok(Mapping::new())
920 }
921
922 #[inline]
923 fn visit_map<A>(self, mut data: A) -> Result<Self::Value, A::Error>
924 where
925 A: serde::de::MapAccess<'de>,
926 {
927 let mut mapping = Mapping::new();
928
929 while let Some(key) = data.next_key()? {
931 match mapping.entry(key) {
933 Entry::Occupied(entry) => {
934 return Err(serde::de::Error::custom(DuplicateKeyError { entry }));
935 }
936 Entry::Vacant(entry) => {
937 let value = data.next_value()?;
939 _ = entry.insert(value);
941 }
942 }
943 }
944
945 Ok(mapping)
946 }
947 }
948
949 deserializer.deserialize_map(Visitor)
950 }
951}
952
953struct DuplicateKeyError<'a> {
954 entry: OccupiedEntry<'a>,
955}
956
957impl std::fmt::Display for DuplicateKeyError<'_> {
958 fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
959 formatter.write_str("duplicate entry ")?;
960 match self.entry.key().as_ref() {
961 Value::Null => formatter.write_str("with null key"),
962 Value::Bool(boolean) => write!(formatter, "with key `{boolean}`"),
963 Value::Number(number) => write!(formatter, "with key {number}"),
964 Value::String(string) => write!(formatter, "with key {string:?}"),
965 Value::Sequence(_) | Value::Mapping(_) | Value::Tagged(_) => {
966 formatter.write_str("in YAML map")
967 }
968 }
969 }
970}
971
972#[cfg(test)]
990mod tests {
991 use crate::{Mapping, Value};
992 use color_eyre::eyre;
993 use indoc::indoc;
994
995 #[test]
996 fn test_mapping() -> eyre::Result<()> {
997 crate::tests::init();
998
999 let yaml = indoc! {"
1000 substructure:
1001 a: 'foo'
1002 b: 'bar'
1003 "};
1004
1005 let value = crate::from_str(yaml)?;
1006 similar_asserts::assert_eq!(
1007 value.clone().cleared_spans().into_inner(),
1008 Value::from(Mapping::from_iter([(
1009 "substructure".into(),
1010 Mapping::from_iter([("a".into(), "foo".into()), ("b".into(), "bar".into()),])
1011 .into()
1012 ),]))
1013 );
1014
1015 #[cfg(feature = "serde")]
1016 {
1017 #[derive(Debug, serde::Deserialize, PartialEq)]
1018 struct Data {
1019 pub substructure: serde_yaml::Mapping,
1020 }
1021
1022 let mut expected = Data {
1023 substructure: serde_yaml::Mapping::new(),
1024 };
1025 expected.substructure.insert(
1026 serde_yaml::Value::String("a".to_owned()),
1027 serde_yaml::Value::String("foo".to_owned()),
1028 );
1029 expected.substructure.insert(
1030 serde_yaml::Value::String("b".to_owned()),
1031 serde_yaml::Value::String("bar".to_owned()),
1032 );
1033
1034 similar_asserts::assert_eq!(crate::from_value::<Data>(&value)?, expected);
1035 }
1036
1037 Ok(())
1038 }
1039}