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