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