1use crate::path::Path;
4use crate::value::{DuplicateKeyCallback, ValueVisitor};
5use crate::{private, Value};
6use indexmap::IndexMap;
7use serde::{Deserialize, Deserializer, Serialize};
8use std::cmp::Ordering;
9use std::collections::hash_map::DefaultHasher;
10use std::fmt::{self, Display};
11use std::hash::{Hash, Hasher};
12use std::mem;
13
14#[derive(Clone, Default, Eq, PartialEq)]
16pub struct Mapping {
17 map: IndexMap<Value, Value>,
18}
19
20impl Mapping {
21 #[inline]
23 pub fn new() -> Self {
24 Self::default()
25 }
26
27 #[inline]
29 pub fn with_capacity(capacity: usize) -> Self {
30 Mapping {
31 map: IndexMap::with_capacity(capacity),
32 }
33 }
34
35 #[inline]
43 pub fn reserve(&mut self, additional: usize) {
44 self.map.reserve(additional);
45 }
46
47 #[inline]
51 pub fn shrink_to_fit(&mut self) {
52 self.map.shrink_to_fit();
53 }
54
55 #[inline]
58 pub fn insert(&mut self, k: Value, v: Value) -> Option<Value> {
59 self.map.insert(k, v)
60 }
61
62 #[inline]
64 pub fn contains_key<I: Index>(&self, index: I) -> bool {
65 index.is_key_into(self)
66 }
67
68 #[inline]
70 pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
71 index.index_into(self)
72 }
73
74 #[inline]
76 pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
77 index.index_into_mut(self)
78 }
79
80 #[inline]
83 pub fn entry(&mut self, k: Value) -> Entry<'_> {
84 match self.map.entry(k) {
85 indexmap::map::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
86 indexmap::map::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
87 }
88 }
89
90 #[inline]
97 pub fn remove<I: Index>(&mut self, index: I) -> Option<Value> {
98 self.swap_remove(index)
99 }
100
101 #[inline]
108 pub fn remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
109 self.swap_remove_entry(index)
110 }
111
112 #[inline]
118 pub fn swap_remove<I: Index>(&mut self, index: I) -> Option<Value> {
119 index.swap_remove_from(self)
120 }
121
122 #[inline]
128 pub fn swap_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
129 index.swap_remove_entry_from(self)
130 }
131
132 #[inline]
138 pub fn shift_remove<I: Index>(&mut self, index: I) -> Option<Value> {
139 index.shift_remove_from(self)
140 }
141
142 #[inline]
148 pub fn shift_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
149 index.shift_remove_entry_from(self)
150 }
151
152 #[inline]
155 pub fn retain<F>(&mut self, keep: F)
156 where
157 F: FnMut(&Value, &mut Value) -> bool,
158 {
159 self.map.retain(keep);
160 }
161
162 #[inline]
165 pub fn capacity(&self) -> usize {
166 self.map.capacity()
167 }
168
169 #[inline]
171 pub fn len(&self) -> usize {
172 self.map.len()
173 }
174
175 #[inline]
177 pub fn is_empty(&self) -> bool {
178 self.map.is_empty()
179 }
180
181 #[inline]
183 pub fn clear(&mut self) {
184 self.map.clear();
185 }
186
187 #[inline]
190 pub fn iter(&self) -> Iter<'_> {
191 Iter {
192 iter: self.map.iter(),
193 }
194 }
195
196 #[inline]
199 pub fn iter_mut(&mut self) -> IterMut<'_> {
200 IterMut {
201 iter: self.map.iter_mut(),
202 }
203 }
204
205 pub fn keys(&self) -> Keys<'_> {
207 Keys {
208 iter: self.map.keys(),
209 }
210 }
211
212 pub fn into_keys(self) -> IntoKeys {
214 IntoKeys {
215 iter: self.map.into_keys(),
216 }
217 }
218
219 pub fn values(&self) -> Values<'_> {
221 Values {
222 iter: self.map.values(),
223 }
224 }
225
226 pub fn values_mut(&mut self) -> ValuesMut<'_> {
228 ValuesMut {
229 iter: self.map.values_mut(),
230 }
231 }
232
233 pub fn into_values(self) -> IntoValues {
235 IntoValues {
236 iter: self.map.into_values(),
237 }
238 }
239}
240
241pub trait Index: private::Sealed {
247 #[doc(hidden)]
248 fn is_key_into(&self, v: &Mapping) -> bool;
249
250 #[doc(hidden)]
251 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>;
252
253 #[doc(hidden)]
254 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>;
255
256 #[doc(hidden)]
257 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value>;
258
259 #[doc(hidden)]
260 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
261
262 #[doc(hidden)]
263 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value>;
264
265 #[doc(hidden)]
266 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
267}
268
269struct HashLikeValue<'a>(&'a str);
270
271impl indexmap::Equivalent<Value> for HashLikeValue<'_> {
272 fn equivalent(&self, key: &Value) -> bool {
273 match key {
274 Value::String(string, ..) => self.0 == string,
275 _ => false,
276 }
277 }
278}
279
280impl Hash for HashLikeValue<'_> {
282 fn hash<H: Hasher>(&self, state: &mut H) {
283 const STRING: Value = Value::string(String::new());
284 mem::discriminant(&STRING).hash(state);
285 self.0.hash(state);
286 }
287}
288
289impl Index for Value {
290 fn is_key_into(&self, v: &Mapping) -> bool {
291 v.map.contains_key(self)
292 }
293 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
294 v.map.get(self)
295 }
296 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
297 v.map.get_mut(self)
298 }
299 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
300 v.map.swap_remove(self)
301 }
302 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
303 v.map.swap_remove_entry(self)
304 }
305 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
306 v.map.shift_remove(self)
307 }
308 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
309 v.map.shift_remove_entry(self)
310 }
311}
312
313impl Index for str {
314 fn is_key_into(&self, v: &Mapping) -> bool {
315 v.map.contains_key(&HashLikeValue(self))
316 }
317 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
318 v.map.get(&HashLikeValue(self))
319 }
320 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
321 v.map.get_mut(&HashLikeValue(self))
322 }
323 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
324 v.map.swap_remove(&HashLikeValue(self))
325 }
326 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
327 v.map.swap_remove_entry(&HashLikeValue(self))
328 }
329 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
330 v.map.shift_remove(&HashLikeValue(self))
331 }
332 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
333 v.map.shift_remove_entry(&HashLikeValue(self))
334 }
335}
336
337impl Index for String {
338 fn is_key_into(&self, v: &Mapping) -> bool {
339 self.as_str().is_key_into(v)
340 }
341 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
342 self.as_str().index_into(v)
343 }
344 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
345 self.as_str().index_into_mut(v)
346 }
347 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
348 self.as_str().swap_remove_from(v)
349 }
350 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
351 self.as_str().swap_remove_entry_from(v)
352 }
353 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
354 self.as_str().shift_remove_from(v)
355 }
356 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
357 self.as_str().shift_remove_entry_from(v)
358 }
359}
360
361impl<T> Index for &T
362where
363 T: ?Sized + Index,
364{
365 fn is_key_into(&self, v: &Mapping) -> bool {
366 (**self).is_key_into(v)
367 }
368 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
369 (**self).index_into(v)
370 }
371 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
372 (**self).index_into_mut(v)
373 }
374 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
375 (**self).swap_remove_from(v)
376 }
377 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
378 (**self).swap_remove_entry_from(v)
379 }
380 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
381 (**self).shift_remove_from(v)
382 }
383 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
384 (**self).shift_remove_entry_from(v)
385 }
386}
387
388#[allow(clippy::derived_hash_with_manual_eq)]
389impl Hash for Mapping {
390 fn hash<H: Hasher>(&self, state: &mut H) {
391 let mut xor = 0;
393 for (k, v) in self {
394 let mut hasher = DefaultHasher::new();
395 k.hash(&mut hasher);
396 v.hash(&mut hasher);
397 xor ^= hasher.finish();
398 }
399 xor.hash(state);
400 }
401}
402
403impl PartialOrd for Mapping {
404 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
405 let mut self_entries = Vec::from_iter(self);
406 let mut other_entries = Vec::from_iter(other);
407
408 fn total_cmp(a: &Value, b: &Value) -> Ordering {
411 match (a, b) {
412 (Value::Null(..), Value::Null(..)) => Ordering::Equal,
413 (Value::Null(..), _) => Ordering::Less,
414 (_, Value::Null(..)) => Ordering::Greater,
415
416 (Value::Bool(a, ..), Value::Bool(b, ..)) => a.cmp(b),
417 (Value::Bool(..), _) => Ordering::Less,
418 (_, Value::Bool(..)) => Ordering::Greater,
419
420 (Value::Number(a, ..), Value::Number(b, ..)) => a.total_cmp(b),
421 (Value::Number(..), _) => Ordering::Less,
422 (_, Value::Number(..)) => Ordering::Greater,
423
424 (Value::String(a, ..), Value::String(b, ..)) => a.cmp(b),
425 (Value::String(..), _) => Ordering::Less,
426 (_, Value::String(..)) => Ordering::Greater,
427
428 (Value::Sequence(a, ..), Value::Sequence(b, ..)) => iter_cmp_by(a, b, total_cmp),
429 (Value::Sequence(..), _) => Ordering::Less,
430 (_, Value::Sequence(..)) => Ordering::Greater,
431
432 (Value::Mapping(a, ..), Value::Mapping(b, ..)) => {
433 iter_cmp_by(a, b, |(ak, av), (bk, bv)| {
434 total_cmp(ak, bk).then_with(|| total_cmp(av, bv))
435 })
436 }
437 (Value::Mapping(..), _) => Ordering::Less,
438 (_, Value::Mapping(..)) => Ordering::Greater,
439
440 (Value::Tagged(a, ..), Value::Tagged(b, ..)) => a
441 .tag
442 .cmp(&b.tag)
443 .then_with(|| total_cmp(&a.value, &b.value)),
444 }
445 }
446
447 fn iter_cmp_by<I, F>(this: I, other: I, mut cmp: F) -> Ordering
448 where
449 I: IntoIterator,
450 F: FnMut(I::Item, I::Item) -> Ordering,
451 {
452 let mut this = this.into_iter();
453 let mut other = other.into_iter();
454
455 loop {
456 let x = match this.next() {
457 None => {
458 if other.next().is_none() {
459 return Ordering::Equal;
460 } else {
461 return Ordering::Less;
462 }
463 }
464 Some(val) => val,
465 };
466
467 let y = match other.next() {
468 None => return Ordering::Greater,
469 Some(val) => val,
470 };
471
472 match cmp(x, y) {
473 Ordering::Equal => {}
474 non_eq => return non_eq,
475 }
476 }
477 }
478
479 let total_cmp = |&(a, _): &_, &(b, _): &_| total_cmp(a, b);
483 self_entries.sort_by(total_cmp);
484 other_entries.sort_by(total_cmp);
485 self_entries.partial_cmp(&other_entries)
486 }
487}
488
489impl<I> std::ops::Index<I> for Mapping
490where
491 I: Index,
492{
493 type Output = Value;
494
495 #[inline]
496 #[track_caller]
497 fn index(&self, index: I) -> &Value {
498 index.index_into(self).unwrap()
499 }
500}
501
502impl<I> std::ops::IndexMut<I> for Mapping
503where
504 I: Index,
505{
506 #[inline]
507 #[track_caller]
508 fn index_mut(&mut self, index: I) -> &mut Value {
509 index.index_into_mut(self).unwrap()
510 }
511}
512
513impl Extend<(Value, Value)> for Mapping {
514 #[inline]
515 fn extend<I: IntoIterator<Item = (Value, Value)>>(&mut self, iter: I) {
516 self.map.extend(iter);
517 }
518}
519
520impl FromIterator<(Value, Value)> for Mapping {
521 #[inline]
522 fn from_iter<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self {
523 Mapping {
524 map: IndexMap::from_iter(iter),
525 }
526 }
527}
528
529macro_rules! delegate_iterator {
530 (($name:ident $($generics:tt)*) => $item:ty) => {
531 impl $($generics)* Iterator for $name $($generics)* {
532 type Item = $item;
533 #[inline]
534 fn next(&mut self) -> Option<Self::Item> {
535 self.iter.next()
536 }
537 #[inline]
538 fn size_hint(&self) -> (usize, Option<usize>) {
539 self.iter.size_hint()
540 }
541 }
542
543 impl $($generics)* ExactSizeIterator for $name $($generics)* {
544 #[inline]
545 fn len(&self) -> usize {
546 self.iter.len()
547 }
548 }
549 }
550}
551
552pub struct Iter<'a> {
554 iter: indexmap::map::Iter<'a, Value, Value>,
555}
556
557delegate_iterator!((Iter<'a>) => (&'a Value, &'a Value));
558
559impl<'a> IntoIterator for &'a Mapping {
560 type Item = (&'a Value, &'a Value);
561 type IntoIter = Iter<'a>;
562 #[inline]
563 fn into_iter(self) -> Self::IntoIter {
564 Iter {
565 iter: self.map.iter(),
566 }
567 }
568}
569
570pub struct IterMut<'a> {
572 iter: indexmap::map::IterMut<'a, Value, Value>,
573}
574
575delegate_iterator!((IterMut<'a>) => (&'a Value, &'a mut Value));
576
577impl<'a> IntoIterator for &'a mut Mapping {
578 type Item = (&'a Value, &'a mut Value);
579 type IntoIter = IterMut<'a>;
580 #[inline]
581 fn into_iter(self) -> Self::IntoIter {
582 IterMut {
583 iter: self.map.iter_mut(),
584 }
585 }
586}
587
588pub struct IntoIter {
590 iter: indexmap::map::IntoIter<Value, Value>,
591}
592
593delegate_iterator!((IntoIter) => (Value, Value));
594
595impl IntoIterator for Mapping {
596 type Item = (Value, Value);
597 type IntoIter = IntoIter;
598 #[inline]
599 fn into_iter(self) -> Self::IntoIter {
600 IntoIter {
601 iter: self.map.into_iter(),
602 }
603 }
604}
605
606pub struct Keys<'a> {
608 iter: indexmap::map::Keys<'a, Value, Value>,
609}
610
611delegate_iterator!((Keys<'a>) => &'a Value);
612
613pub struct IntoKeys {
615 iter: indexmap::map::IntoKeys<Value, Value>,
616}
617
618delegate_iterator!((IntoKeys) => Value);
619
620pub struct Values<'a> {
622 iter: indexmap::map::Values<'a, Value, Value>,
623}
624
625delegate_iterator!((Values<'a>) => &'a Value);
626
627pub struct ValuesMut<'a> {
629 iter: indexmap::map::ValuesMut<'a, Value, Value>,
630}
631
632delegate_iterator!((ValuesMut<'a>) => &'a mut Value);
633
634pub struct IntoValues {
636 iter: indexmap::map::IntoValues<Value, Value>,
637}
638
639delegate_iterator!((IntoValues) => Value);
640
641pub enum Entry<'a> {
643 Occupied(OccupiedEntry<'a>),
645 Vacant(VacantEntry<'a>),
647}
648
649pub struct OccupiedEntry<'a> {
652 occupied: indexmap::map::OccupiedEntry<'a, Value, Value>,
653}
654
655pub struct VacantEntry<'a> {
658 vacant: indexmap::map::VacantEntry<'a, Value, Value>,
659}
660
661impl<'a> Entry<'a> {
662 pub fn key(&self) -> &Value {
664 match self {
665 Entry::Vacant(e) => e.key(),
666 Entry::Occupied(e) => e.key(),
667 }
668 }
669
670 pub fn or_insert(self, default: Value) -> &'a mut Value {
673 match self {
674 Entry::Vacant(entry) => entry.insert(default),
675 Entry::Occupied(entry) => entry.into_mut(),
676 }
677 }
678
679 pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
683 where
684 F: FnOnce() -> Value,
685 {
686 match self {
687 Entry::Vacant(entry) => entry.insert(default()),
688 Entry::Occupied(entry) => entry.into_mut(),
689 }
690 }
691
692 pub fn and_modify<F>(self, f: F) -> Self
695 where
696 F: FnOnce(&mut Value),
697 {
698 match self {
699 Entry::Occupied(mut entry) => {
700 f(entry.get_mut());
701 Entry::Occupied(entry)
702 }
703 Entry::Vacant(entry) => Entry::Vacant(entry),
704 }
705 }
706}
707
708impl<'a> OccupiedEntry<'a> {
709 #[inline]
711 pub fn key(&self) -> &Value {
712 self.occupied.key()
713 }
714
715 #[inline]
717 pub fn get(&self) -> &Value {
718 self.occupied.get()
719 }
720
721 #[inline]
723 pub fn get_mut(&mut self) -> &mut Value {
724 self.occupied.get_mut()
725 }
726
727 #[inline]
729 pub fn into_mut(self) -> &'a mut Value {
730 self.occupied.into_mut()
731 }
732
733 #[inline]
736 pub fn insert(&mut self, value: Value) -> Value {
737 self.occupied.insert(value)
738 }
739
740 #[inline]
742 pub fn remove(self) -> Value {
743 self.occupied.swap_remove()
744 }
745
746 #[inline]
748 pub fn remove_entry(self) -> (Value, Value) {
749 self.occupied.swap_remove_entry()
750 }
751}
752
753impl<'a> VacantEntry<'a> {
754 #[inline]
757 pub fn key(&self) -> &Value {
758 self.vacant.key()
759 }
760
761 #[inline]
763 pub fn into_key(self) -> Value {
764 self.vacant.into_key()
765 }
766
767 #[inline]
770 pub fn insert(self, value: Value) -> &'a mut Value {
771 self.vacant.insert(value)
772 }
773}
774
775impl Serialize for Mapping {
776 #[inline]
777 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
778 use serde::ser::SerializeMap;
779 let mut map_serializer = serializer.serialize_map(Some(self.len()))?;
780 for (k, v) in self {
781 map_serializer.serialize_entry(k, v)?;
782 }
783 map_serializer.end()
784 }
785}
786
787impl<'de> Deserialize<'de> for Mapping {
788 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
789 where
790 D: Deserializer<'de>,
791 {
792 deserializer.deserialize_map(MappingVisitor {
793 callback: &mut |_, _, _| DuplicateKey::Error,
794 path: Path::Root,
795 })
796 }
797}
798
799struct DuplicateKeyError<'a> {
800 entry: OccupiedEntry<'a>,
801}
802
803impl Display for DuplicateKeyError<'_> {
804 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
805 formatter.write_str("duplicate entry ")?;
806 match self.entry.key() {
807 Value::Null(..) => formatter.write_str("with null key"),
808 Value::Bool(boolean, ..) => write!(formatter, "with key `{}`", boolean),
809 Value::Number(number, ..) => write!(formatter, "with key {}", number),
810 Value::String(string, ..) => write!(formatter, "with key {:?}", string),
811 Value::Sequence(..) | Value::Mapping(..) | Value::Tagged(..) => {
812 formatter.write_str("in YAML map")
813 }
814 }
815 }
816}
817
818pub enum DuplicateKey {
821 Error,
823 Ignore,
825 Overwrite,
827}
828
829pub(crate) struct MappingVisitor<'d, 'b> {
830 pub callback: DuplicateKeyCallback<'d>,
831 pub path: Path<'b>,
832}
833
834impl<'de> serde::de::Visitor<'de> for MappingVisitor<'_, '_> {
835 type Value = Mapping;
836
837 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
838 formatter.write_str("a YAML mapping")
839 }
840
841 #[inline]
842 fn visit_unit<E>(self) -> Result<Self::Value, E>
843 where
844 E: serde::de::Error,
845 {
846 Ok(Mapping::new())
847 }
848
849 #[inline]
850 fn visit_map<A>(self, mut data: A) -> Result<Self::Value, A::Error>
851 where
852 A: serde::de::MapAccess<'de>,
853 {
854 let mut mapping = Mapping::new();
855 let callback = &mut *self.callback;
856
857 while let Some(key) = data.next_key_seed(ValueVisitor {
858 callback,
859 path: self.path,
860 })? {
861 let path = if let Some(key) = key.as_str() {
862 Path::Map {
863 parent: &self.path,
864 key,
865 }
866 } else {
867 Path::Unknown { parent: &self.path }
868 };
869
870 if let Some((existing_key, _)) = mapping.map.get_key_value(&key) {
871 match callback(path, &key, existing_key) {
872 DuplicateKey::Error => {
873 let entry = match mapping.entry(key) {
874 Entry::Occupied(entry) => entry,
875 Entry::Vacant(_) => unreachable!(),
876 };
877
878 return Err(serde::de::Error::custom(DuplicateKeyError { entry }));
879 }
880 DuplicateKey::Ignore => {
881 let _ = data.next_value_seed(ValueVisitor { callback, path })?;
882 }
883 DuplicateKey::Overwrite => {
884 let value = data.next_value_seed(ValueVisitor { callback, path })?;
885 mapping.insert(key, value);
886 }
887 }
888 } else {
889 let value = data.next_value_seed(ValueVisitor { callback, path })?;
890 mapping.insert(key, value);
891 }
892 }
893
894 Ok(mapping)
895 }
896}