1use std::{
4 cmp::Ordering,
5 collections::hash_map::DefaultHasher,
6 fmt::{self, Display},
7 hash::{Hash, Hasher},
8 mem,
9};
10
11use indexmap::IndexMap;
12use serde::{Deserialize, Deserializer, Serialize};
13
14use crate::{Value, private};
15
16#[derive(Clone, Default, Eq, PartialEq)]
18pub struct Mapping {
19 map: IndexMap<Value, Value>,
20}
21
22impl Mapping {
23 #[inline]
25 pub fn new() -> Self {
26 Self::default()
27 }
28
29 #[inline]
31 pub fn with_capacity(capacity: usize) -> Self {
32 Mapping {
33 map: IndexMap::with_capacity(capacity),
34 }
35 }
36
37 #[inline]
45 pub fn reserve(&mut self, additional: usize) {
46 self.map.reserve(additional);
47 }
48
49 #[inline]
53 pub fn shrink_to_fit(&mut self) {
54 self.map.shrink_to_fit();
55 }
56
57 #[inline]
60 pub fn insert(&mut self, k: Value, v: Value) -> Option<Value> {
61 self.map.insert(k, v)
62 }
63
64 #[inline]
66 pub fn contains_key<I: Index>(&self, index: I) -> bool {
67 index.is_key_into(self)
68 }
69
70 #[inline]
72 pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
73 index.index_into(self)
74 }
75
76 #[inline]
78 pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
79 index.index_into_mut(self)
80 }
81
82 #[inline]
85 pub fn entry(&mut self, k: Value) -> Entry {
86 match self.map.entry(k) {
87 indexmap::map::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry {
88 occupied,
89 }),
90 indexmap::map::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry {
91 vacant,
92 }),
93 }
94 }
95
96 #[inline]
103 pub fn remove<I: Index>(&mut self, index: I) -> Option<Value> {
104 self.swap_remove(index)
105 }
106
107 #[inline]
114 pub fn remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
115 self.swap_remove_entry(index)
116 }
117
118 #[inline]
124 pub fn swap_remove<I: Index>(&mut self, index: I) -> Option<Value> {
125 index.swap_remove_from(self)
126 }
127
128 #[inline]
134 pub fn swap_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
135 index.swap_remove_entry_from(self)
136 }
137
138 #[inline]
144 pub fn shift_remove<I: Index>(&mut self, index: I) -> Option<Value> {
145 index.shift_remove_from(self)
146 }
147
148 #[inline]
154 pub fn shift_remove_entry<I: Index>(&mut self, index: I) -> Option<(Value, Value)> {
155 index.shift_remove_entry_from(self)
156 }
157
158 #[inline]
161 pub fn retain<F>(&mut self, keep: F)
162 where
163 F: FnMut(&Value, &mut Value) -> bool,
164 {
165 self.map.retain(keep);
166 }
167
168 #[inline]
171 pub fn capacity(&self) -> usize {
172 self.map.capacity()
173 }
174
175 #[inline]
177 pub fn len(&self) -> usize {
178 self.map.len()
179 }
180
181 #[inline]
183 pub fn is_empty(&self) -> bool {
184 self.map.is_empty()
185 }
186
187 #[inline]
189 pub fn clear(&mut self) {
190 self.map.clear();
191 }
192
193 #[inline]
196 pub fn iter(&self) -> Iter {
197 Iter {
198 iter: self.map.iter(),
199 }
200 }
201
202 #[inline]
205 pub fn iter_mut(&mut self) -> IterMut {
206 IterMut {
207 iter: self.map.iter_mut(),
208 }
209 }
210
211 pub fn keys(&self) -> Keys {
213 Keys {
214 iter: self.map.keys(),
215 }
216 }
217
218 pub fn into_keys(self) -> IntoKeys {
220 IntoKeys {
221 iter: self.map.into_keys(),
222 }
223 }
224
225 pub fn values(&self) -> Values {
227 Values {
228 iter: self.map.values(),
229 }
230 }
231
232 pub fn values_mut(&mut self) -> ValuesMut {
234 ValuesMut {
235 iter: self.map.values_mut(),
236 }
237 }
238
239 pub fn into_values(self) -> IntoValues {
241 IntoValues {
242 iter: self.map.into_values(),
243 }
244 }
245}
246
247pub trait Index: private::Sealed {
253 #[doc(hidden)]
254 fn is_key_into(&self, v: &Mapping) -> bool;
255
256 #[doc(hidden)]
257 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value>;
258
259 #[doc(hidden)]
260 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value>;
261
262 #[doc(hidden)]
263 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value>;
264
265 #[doc(hidden)]
266 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
267
268 #[doc(hidden)]
269 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value>;
270
271 #[doc(hidden)]
272 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)>;
273}
274
275struct HashLikeValue<'a>(&'a str);
276
277impl<'a> indexmap::Equivalent<Value> for HashLikeValue<'a> {
278 fn equivalent(&self, key: &Value) -> bool {
279 match key {
280 Value::String(string) => self.0 == string,
281 _ => false,
282 }
283 }
284}
285
286impl<'a> Hash for HashLikeValue<'a> {
288 fn hash<H: Hasher>(&self, state: &mut H) {
289 const STRING: Value = Value::String(String::new());
290 mem::discriminant(&STRING).hash(state);
291 self.0.hash(state);
292 }
293}
294
295impl Index for Value {
296 fn is_key_into(&self, v: &Mapping) -> bool {
297 v.map.contains_key(self)
298 }
299 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
300 v.map.get(self)
301 }
302 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
303 v.map.get_mut(self)
304 }
305 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
306 v.map.swap_remove(self)
307 }
308 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
309 v.map.swap_remove_entry(self)
310 }
311 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
312 v.map.shift_remove(self)
313 }
314 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
315 v.map.shift_remove_entry(self)
316 }
317}
318
319impl Index for str {
320 fn is_key_into(&self, v: &Mapping) -> bool {
321 v.map.contains_key(&HashLikeValue(self))
322 }
323 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
324 v.map.get(&HashLikeValue(self))
325 }
326 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
327 v.map.get_mut(&HashLikeValue(self))
328 }
329 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
330 v.map.swap_remove(&HashLikeValue(self))
331 }
332 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
333 v.map.swap_remove_entry(&HashLikeValue(self))
334 }
335 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
336 v.map.shift_remove(&HashLikeValue(self))
337 }
338 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
339 v.map.shift_remove_entry(&HashLikeValue(self))
340 }
341}
342
343impl Index for String {
344 fn is_key_into(&self, v: &Mapping) -> bool {
345 self.as_str().is_key_into(v)
346 }
347 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
348 self.as_str().index_into(v)
349 }
350 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
351 self.as_str().index_into_mut(v)
352 }
353 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
354 self.as_str().swap_remove_from(v)
355 }
356 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
357 self.as_str().swap_remove_entry_from(v)
358 }
359 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
360 self.as_str().shift_remove_from(v)
361 }
362 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
363 self.as_str().shift_remove_entry_from(v)
364 }
365}
366
367impl<T> Index for &T
368where
369 T: ?Sized + Index,
370{
371 fn is_key_into(&self, v: &Mapping) -> bool {
372 (**self).is_key_into(v)
373 }
374 fn index_into<'a>(&self, v: &'a Mapping) -> Option<&'a Value> {
375 (**self).index_into(v)
376 }
377 fn index_into_mut<'a>(&self, v: &'a mut Mapping) -> Option<&'a mut Value> {
378 (**self).index_into_mut(v)
379 }
380 fn swap_remove_from(&self, v: &mut Mapping) -> Option<Value> {
381 (**self).swap_remove_from(v)
382 }
383 fn swap_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
384 (**self).swap_remove_entry_from(v)
385 }
386 fn shift_remove_from(&self, v: &mut Mapping) -> Option<Value> {
387 (**self).shift_remove_from(v)
388 }
389 fn shift_remove_entry_from(&self, v: &mut Mapping) -> Option<(Value, Value)> {
390 (**self).shift_remove_entry_from(v)
391 }
392}
393
394#[allow(clippy::derived_hash_with_manual_eq)]
395impl Hash for Mapping {
396 fn hash<H: Hasher>(&self, state: &mut H) {
397 let mut xor = 0;
399 for (k, v) in self {
400 let mut hasher = DefaultHasher::new();
401 k.hash(&mut hasher);
402 v.hash(&mut hasher);
403 xor ^= hasher.finish();
404 }
405 xor.hash(state);
406 }
407}
408
409impl PartialOrd for Mapping {
410 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
411 let mut self_entries = Vec::from_iter(self);
412 let mut other_entries = Vec::from_iter(other);
413
414 fn total_cmp(a: &Value, b: &Value) -> Ordering {
417 match (a, b) {
418 (Value::Null, Value::Null) => Ordering::Equal,
419 (Value::Null, _) => Ordering::Less,
420 (_, Value::Null) => Ordering::Greater,
421
422 (Value::Bool(a), Value::Bool(b)) => a.cmp(b),
423 (Value::Bool(_), _) => Ordering::Less,
424 (_, Value::Bool(_)) => Ordering::Greater,
425
426 (Value::Number(a), Value::Number(b)) => a.total_cmp(b),
427 (Value::Number(_), _) => Ordering::Less,
428 (_, Value::Number(_)) => Ordering::Greater,
429
430 (Value::String(a), Value::String(b)) => a.cmp(b),
431 (Value::String(_), _) => Ordering::Less,
432 (_, Value::String(_)) => Ordering::Greater,
433
434 (Value::Sequence(a), Value::Sequence(b)) => iter_cmp_by(a, b, total_cmp),
435 (Value::Sequence(_), _) => Ordering::Less,
436 (_, Value::Sequence(_)) => Ordering::Greater,
437
438 (Value::Mapping(a), Value::Mapping(b)) => {
439 iter_cmp_by(a, b, |(ak, av), (bk, bv)| total_cmp(ak, bk).then_with(|| total_cmp(av, bv)))
440 }
441 (Value::Mapping(_), _) => Ordering::Less,
442 (_, Value::Mapping(_)) => Ordering::Greater,
443
444 (Value::Tagged(a), Value::Tagged(b)) => a.tag.cmp(&b.tag).then_with(|| total_cmp(&a.value, &b.value)),
445 }
446 }
447
448 fn iter_cmp_by<I, F>(this: I, other: I, mut cmp: F) -> Ordering
449 where
450 I: IntoIterator,
451 F: FnMut(I::Item, I::Item) -> Ordering,
452 {
453 let mut this = this.into_iter();
454 let mut other = other.into_iter();
455
456 loop {
457 let x = match this.next() {
458 None => {
459 if other.next().is_none() {
460 return Ordering::Equal;
461 } else {
462 return Ordering::Less;
463 }
464 }
465 Some(val) => val,
466 };
467
468 let y = match other.next() {
469 None => return Ordering::Greater,
470 Some(val) => val,
471 };
472
473 match cmp(x, y) {
474 Ordering::Equal => {}
475 non_eq => return non_eq,
476 }
477 }
478 }
479
480 let total_cmp = |&(a, _): &_, &(b, _): &_| total_cmp(a, b);
484 self_entries.sort_by(total_cmp);
485 other_entries.sort_by(total_cmp);
486 self_entries.partial_cmp(&other_entries)
487 }
488}
489
490impl<I> std::ops::Index<I> for Mapping
491where
492 I: Index,
493{
494 type Output = Value;
495
496 #[inline]
497 #[track_caller]
498 fn index(&self, index: I) -> &Value {
499 index.index_into(self).unwrap()
500 }
501}
502
503impl<I> std::ops::IndexMut<I> for Mapping
504where
505 I: Index,
506{
507 #[inline]
508 #[track_caller]
509 fn index_mut(&mut self, index: I) -> &mut Value {
510 index.index_into_mut(self).unwrap()
511 }
512}
513
514impl Extend<(Value, Value)> for Mapping {
515 #[inline]
516 fn extend<I: IntoIterator<Item = (Value, Value)>>(&mut self, iter: I) {
517 self.map.extend(iter);
518 }
519}
520
521impl FromIterator<(Value, Value)> for Mapping {
522 #[inline]
523 fn from_iter<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self {
524 Mapping {
525 map: IndexMap::from_iter(iter),
526 }
527 }
528}
529
530macro_rules! delegate_iterator {
531 (($name:ident $($generics:tt)*) => $item:ty) => {
532 impl $($generics)* Iterator for $name $($generics)* {
533 type Item = $item;
534 #[inline]
535 fn next(&mut self) -> Option<Self::Item> {
536 self.iter.next()
537 }
538 #[inline]
539 fn size_hint(&self) -> (usize, Option<usize>) {
540 self.iter.size_hint()
541 }
542 }
543
544 impl $($generics)* ExactSizeIterator for $name $($generics)* {
545 #[inline]
546 fn len(&self) -> usize {
547 self.iter.len()
548 }
549 }
550 }
551}
552
553pub struct Iter<'a> {
555 iter: indexmap::map::Iter<'a, Value, Value>,
556}
557
558delegate_iterator!((Iter<'a>) => (&'a Value, &'a Value));
559
560impl<'a> IntoIterator for &'a Mapping {
561 type Item = (&'a Value, &'a Value);
562 type IntoIter = Iter<'a>;
563 #[inline]
564 fn into_iter(self) -> Self::IntoIter {
565 Iter {
566 iter: self.map.iter(),
567 }
568 }
569}
570
571pub struct IterMut<'a> {
573 iter: indexmap::map::IterMut<'a, Value, Value>,
574}
575
576delegate_iterator!((IterMut<'a>) => (&'a Value, &'a mut Value));
577
578impl<'a> IntoIterator for &'a mut Mapping {
579 type Item = (&'a Value, &'a mut Value);
580 type IntoIter = IterMut<'a>;
581 #[inline]
582 fn into_iter(self) -> Self::IntoIter {
583 IterMut {
584 iter: self.map.iter_mut(),
585 }
586 }
587}
588
589pub struct IntoIter {
591 iter: indexmap::map::IntoIter<Value, Value>,
592}
593
594delegate_iterator!((IntoIter) => (Value, Value));
595
596impl IntoIterator for Mapping {
597 type Item = (Value, Value);
598 type IntoIter = IntoIter;
599 #[inline]
600 fn into_iter(self) -> Self::IntoIter {
601 IntoIter {
602 iter: self.map.into_iter(),
603 }
604 }
605}
606
607pub struct Keys<'a> {
609 iter: indexmap::map::Keys<'a, Value, Value>,
610}
611
612delegate_iterator!((Keys<'a>) => &'a Value);
613
614pub struct IntoKeys {
616 iter: indexmap::map::IntoKeys<Value, Value>,
617}
618
619delegate_iterator!((IntoKeys) => Value);
620
621pub struct Values<'a> {
623 iter: indexmap::map::Values<'a, Value, Value>,
624}
625
626delegate_iterator!((Values<'a>) => &'a Value);
627
628pub struct ValuesMut<'a> {
630 iter: indexmap::map::ValuesMut<'a, Value, Value>,
631}
632
633delegate_iterator!((ValuesMut<'a>) => &'a mut Value);
634
635pub struct IntoValues {
637 iter: indexmap::map::IntoValues<Value, Value>,
638}
639
640delegate_iterator!((IntoValues) => Value);
641
642pub enum Entry<'a> {
644 Occupied(OccupiedEntry<'a>),
646 Vacant(VacantEntry<'a>),
648}
649
650pub struct OccupiedEntry<'a> {
653 occupied: indexmap::map::OccupiedEntry<'a, Value, Value>,
654}
655
656pub struct VacantEntry<'a> {
659 vacant: indexmap::map::VacantEntry<'a, Value, Value>,
660}
661
662impl<'a> Entry<'a> {
663 pub fn key(&self) -> &Value {
665 match self {
666 Entry::Vacant(e) => e.key(),
667 Entry::Occupied(e) => e.key(),
668 }
669 }
670
671 pub fn or_insert(self, default: Value) -> &'a mut Value {
674 match self {
675 Entry::Vacant(entry) => entry.insert(default),
676 Entry::Occupied(entry) => entry.into_mut(),
677 }
678 }
679
680 pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
684 where
685 F: FnOnce() -> Value,
686 {
687 match self {
688 Entry::Vacant(entry) => entry.insert(default()),
689 Entry::Occupied(entry) => entry.into_mut(),
690 }
691 }
692
693 pub fn and_modify<F>(self, f: F) -> Self
696 where
697 F: FnOnce(&mut Value),
698 {
699 match self {
700 Entry::Occupied(mut entry) => {
701 f(entry.get_mut());
702 Entry::Occupied(entry)
703 }
704 Entry::Vacant(entry) => Entry::Vacant(entry),
705 }
706 }
707}
708
709impl<'a> OccupiedEntry<'a> {
710 #[inline]
712 pub fn key(&self) -> &Value {
713 self.occupied.key()
714 }
715
716 #[inline]
718 pub fn get(&self) -> &Value {
719 self.occupied.get()
720 }
721
722 #[inline]
724 pub fn get_mut(&mut self) -> &mut Value {
725 self.occupied.get_mut()
726 }
727
728 #[inline]
730 pub fn into_mut(self) -> &'a mut Value {
731 self.occupied.into_mut()
732 }
733
734 #[inline]
737 pub fn insert(&mut self, value: Value) -> Value {
738 self.occupied.insert(value)
739 }
740
741 #[inline]
743 pub fn remove(self) -> Value {
744 self.occupied.swap_remove()
745 }
746
747 #[inline]
749 pub fn remove_entry(self) -> (Value, Value) {
750 self.occupied.swap_remove_entry()
751 }
752}
753
754impl<'a> VacantEntry<'a> {
755 #[inline]
758 pub fn key(&self) -> &Value {
759 self.vacant.key()
760 }
761
762 #[inline]
764 pub fn into_key(self) -> Value {
765 self.vacant.into_key()
766 }
767
768 #[inline]
771 pub fn insert(self, value: Value) -> &'a mut Value {
772 self.vacant.insert(value)
773 }
774}
775
776impl Serialize for Mapping {
777 #[inline]
778 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
779 use serde::ser::SerializeMap;
780 let mut map_serializer = serializer.serialize_map(Some(self.len()))?;
781 for (k, v) in self {
782 map_serializer.serialize_entry(k, v)?;
783 }
784 map_serializer.end()
785 }
786}
787
788impl<'de> Deserialize<'de> for Mapping {
789 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
790 where
791 D: Deserializer<'de>,
792 {
793 struct Visitor;
794
795 impl<'de> serde::de::Visitor<'de> for Visitor {
796 type Value = Mapping;
797
798 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
799 formatter.write_str("a YAML mapping")
800 }
801
802 #[inline]
803 fn visit_unit<E>(self) -> Result<Self::Value, E>
804 where
805 E: serde::de::Error,
806 {
807 Ok(Mapping::new())
808 }
809
810 #[inline]
811 fn visit_map<A>(self, mut data: A) -> Result<Self::Value, A::Error>
812 where
813 A: serde::de::MapAccess<'de>,
814 {
815 let mut mapping = Mapping::new();
816
817 while let Some(key) = data.next_key()? {
818 match mapping.entry(key) {
819 Entry::Occupied(entry) => {
820 return Err(serde::de::Error::custom(DuplicateKeyError {
821 entry,
822 }));
823 }
824 Entry::Vacant(entry) => {
825 let value = data.next_value()?;
826 entry.insert(value);
827 }
828 }
829 }
830
831 Ok(mapping)
832 }
833 }
834
835 deserializer.deserialize_map(Visitor)
836 }
837}
838
839struct DuplicateKeyError<'a> {
840 entry: OccupiedEntry<'a>,
841}
842
843impl<'a> Display for DuplicateKeyError<'a> {
844 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
845 formatter.write_str("duplicate entry ")?;
846 match self.entry.key() {
847 Value::Null => formatter.write_str("with null key"),
848 Value::Bool(boolean) => write!(formatter, "with key `{}`", boolean),
849 Value::Number(number) => write!(formatter, "with key {}", number),
850 Value::String(string) => write!(formatter, "with key {:?}", string),
851 Value::Sequence(_) | Value::Mapping(_) | Value::Tagged(_) => formatter.write_str("in YAML map"),
852 }
853 }
854}