1use std::{
2 borrow::Borrow,
3 fmt::{self, Debug},
4 hash::Hash,
5 ops::{Deref, DerefMut},
6};
7
8use crate::{
9 common::{UnknownEntries, UnknownEntriesNone, UnknownEntriesSome},
10 untagged::{BoxDataTypeDowncast, BoxDt, DataTypeWrapper, FromDataType},
11};
12
13#[cfg(not(feature = "ordered"))]
14use std::collections::HashMap as Map;
15
16#[cfg(feature = "ordered")]
17use indexmap::IndexMap as Map;
18
19#[derive(serde::Serialize)]
21#[serde(transparent)]
22pub struct TypeMap<K, BoxDT = BoxDt, UnknownEntriesT = UnknownEntriesNone>
23where
24 K: Eq + Hash,
25 UnknownEntriesT: UnknownEntries,
26{
27 inner: Map<K, BoxDT>,
29 #[serde(skip_serializing)]
31 unknown_entries: Map<K, <UnknownEntriesT as UnknownEntries>::ValueT>,
32}
33
34impl<K> TypeMap<K, BoxDt>
35where
36 K: Eq + Hash,
37{
38 pub fn new() -> Self {
50 Self {
51 inner: Map::new(),
52 unknown_entries: Map::new(),
53 }
54 }
55
56 pub fn with_capacity(capacity: usize) -> Self {
68 Self {
69 inner: Map::with_capacity(capacity),
70 unknown_entries: Map::new(),
71 }
72 }
73}
74
75impl<K, BoxDT> TypeMap<K, BoxDT, UnknownEntriesNone>
76where
77 K: Eq + Hash,
78 BoxDT: DataTypeWrapper,
79{
80 pub fn into_inner(self) -> Map<K, BoxDT> {
82 self.inner
83 }
84}
85
86impl<K, BoxDT, ValueT> TypeMap<K, BoxDT, UnknownEntriesSome<ValueT>>
87where
88 K: Eq + Hash,
89 BoxDT: DataTypeWrapper,
90 ValueT: Clone + Debug + PartialEq + Eq,
91{
92 pub fn into_inner(self) -> (Map<K, BoxDT>, Map<K, ValueT>) {
94 (self.inner, self.unknown_entries)
95 }
96
97 pub fn unknown_entries(&self) -> &Map<K, ValueT> {
104 &self.unknown_entries
105 }
106
107 pub fn get_unknown_entry<Q>(&self, q: &Q) -> Option<&ValueT>
163 where
164 K: Borrow<Q>,
165 Q: Hash + Eq + ?Sized,
166 {
167 self.unknown_entries().get(q)
168 }
169
170 pub(crate) fn insert_unknown_entry(&mut self, k: K, v: ValueT) -> Option<ValueT> {
180 self.unknown_entries.insert(k, v)
181 }
182}
183
184impl<K, BoxDT, UnknownEntriesT> TypeMap<K, BoxDT, UnknownEntriesT>
185where
186 K: Eq + Hash,
187 BoxDT: DataTypeWrapper,
188 UnknownEntriesT: UnknownEntries,
189{
190 pub fn new_typed() -> Self {
202 Self {
203 inner: Map::new(),
204 unknown_entries: Map::new(),
205 }
206 }
207
208 pub fn with_capacity_typed(capacity: usize) -> Self {
220 Self {
221 inner: Map::with_capacity(capacity),
222 unknown_entries: Map::new(),
223 }
224 }
225
226 #[cfg(not(feature = "debug"))]
246 pub fn get<R, Q>(&self, q: &Q) -> Option<&R>
247 where
248 K: Borrow<Q>,
249 BoxDT: BoxDataTypeDowncast<R>,
250 Q: Hash + Eq + ?Sized,
251 R: Clone + serde::Serialize + Send + Sync + 'static,
252 {
253 self.inner
254 .get(q)
255 .and_then(BoxDataTypeDowncast::<R>::downcast_ref)
256 }
257
258 #[cfg(feature = "debug")]
278 pub fn get<R, Q>(&self, q: &Q) -> Option<&R>
279 where
280 K: Borrow<Q>,
281 BoxDT: BoxDataTypeDowncast<R>,
282 Q: Hash + Eq + ?Sized,
283 R: Clone + Debug + serde::Serialize + Send + Sync + 'static,
284 {
285 self.inner
286 .get(q)
287 .and_then(BoxDataTypeDowncast::<R>::downcast_ref)
288 }
289
290 #[cfg(not(feature = "debug"))]
311 pub fn get_mut<R, Q>(&mut self, q: &Q) -> Option<&mut R>
312 where
313 K: Borrow<Q>,
314 BoxDT: BoxDataTypeDowncast<R>,
315 Q: Hash + Eq + ?Sized,
316 R: Clone + serde::Serialize + Send + Sync + 'static,
317 {
318 self.inner
319 .get_mut(q)
320 .and_then(BoxDataTypeDowncast::<R>::downcast_mut)
321 }
322
323 #[cfg(feature = "debug")]
343 pub fn get_mut<R, Q>(&mut self, q: &Q) -> Option<&mut R>
344 where
345 K: Borrow<Q>,
346 BoxDT: BoxDataTypeDowncast<R>,
347 Q: Hash + Eq + ?Sized,
348 R: Clone + Debug + serde::Serialize + Send + Sync + 'static,
349 {
350 self.inner
351 .get_mut(q)
352 .and_then(BoxDataTypeDowncast::<R>::downcast_mut)
353 }
354
355 pub fn get_raw<Q>(&self, q: &Q) -> Option<&BoxDT>
378 where
379 K: Borrow<Q>,
380 Q: Hash + Eq + ?Sized,
381 {
382 self.inner.get(q)
383 }
384
385 pub fn get_raw_mut<Q>(&mut self, q: &Q) -> Option<&mut BoxDT>
413 where
414 K: Borrow<Q>,
415 Q: Hash + Eq + ?Sized,
416 {
417 self.inner.get_mut(q)
418 }
419
420 #[cfg(not(feature = "debug"))]
428 pub fn insert<R>(&mut self, k: K, r: R) -> Option<BoxDT>
429 where
430 BoxDT: FromDataType<R>,
431 {
432 self.inner.insert(k, <BoxDT as FromDataType<R>>::from(r))
433 }
434
435 #[cfg(feature = "debug")]
443 pub fn insert<R>(&mut self, k: K, r: R) -> Option<BoxDT>
444 where
445 BoxDT: FromDataType<R>,
446 {
447 self.inner.insert(k, <BoxDT as FromDataType<R>>::from(r))
448 }
449
450 pub fn insert_raw(&mut self, k: K, v: BoxDT) -> Option<BoxDT> {
458 self.inner.insert(k, v)
459 }
460}
461
462impl<K, BoxDT, UnknownEntriesT> Clone for TypeMap<K, BoxDT, UnknownEntriesT>
463where
464 K: Clone + Eq + Hash,
465 BoxDT: DataTypeWrapper,
466 UnknownEntriesT: UnknownEntries,
467{
468 fn clone(&self) -> Self {
469 let mut type_map = TypeMap::<K, BoxDT, UnknownEntriesT> {
470 inner: Map::with_capacity(self.inner.len()),
471 unknown_entries: Map::with_capacity(self.unknown_entries.len()),
472 };
473 self.inner.iter().for_each(|(k, v)| {
474 let value = v.clone();
475 type_map.insert_raw(k.clone(), value);
476 });
477 self.unknown_entries.iter().for_each(|(k, v)| {
478 let k = k.clone();
479 let v = v.clone();
480 type_map.unknown_entries.insert(k, v);
481 });
482 type_map
483 }
484}
485
486impl<K, BoxDT, UnknownEntriesT> Default for TypeMap<K, BoxDT, UnknownEntriesT>
487where
488 K: Eq + Hash,
489 UnknownEntriesT: UnknownEntries,
490{
491 fn default() -> Self {
492 Self {
493 inner: Map::default(),
494 unknown_entries: Map::default(),
495 }
496 }
497}
498
499impl<K, BoxDT, UnknownEntriesT> Deref for TypeMap<K, BoxDT, UnknownEntriesT>
500where
501 K: Eq + Hash,
502 UnknownEntriesT: UnknownEntries,
503{
504 type Target = Map<K, BoxDT>;
505
506 fn deref(&self) -> &Self::Target {
507 &self.inner
508 }
509}
510
511impl<K, BoxDT, UnknownEntriesT> DerefMut for TypeMap<K, BoxDT, UnknownEntriesT>
512where
513 K: Eq + Hash,
514 UnknownEntriesT: UnknownEntries,
515{
516 fn deref_mut(&mut self) -> &mut Self::Target {
517 &mut self.inner
518 }
519}
520
521impl<K, BoxDT> Debug for TypeMap<K, BoxDT, UnknownEntriesNone>
522where
523 K: Eq + Hash + Debug,
524 BoxDT: DataTypeWrapper,
525{
526 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
527 let mut debug_map = f.debug_map();
528
529 self.inner.iter().for_each(|(k, resource)| {
530 #[cfg(not(feature = "debug"))]
532 let value = &"..";
533
534 #[cfg(feature = "debug")]
535 let value = resource.debug();
536
537 let type_name = resource.type_name();
538 let debug_value = crate::TypedValue {
539 r#type: type_name,
540 value,
541 };
542
543 debug_map.key(&k);
544 debug_map.value(&debug_value);
545 });
546
547 debug_map.finish()
548 }
549}
550
551struct InnerWrapper<'inner, K, BoxDT>
552where
553 K: Eq + Hash + Debug,
554 BoxDT: DataTypeWrapper,
555{
556 inner: &'inner Map<K, BoxDT>,
557}
558
559impl<K, BoxDT> Debug for InnerWrapper<'_, K, BoxDT>
560where
561 K: Eq + Hash + Debug,
562 BoxDT: DataTypeWrapper,
563{
564 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
565 let mut debug_map = f.debug_map();
566
567 self.inner.iter().for_each(|(k, resource)| {
568 #[cfg(not(feature = "debug"))]
570 let value = &"..";
571
572 #[cfg(feature = "debug")]
573 let value = resource.debug();
574
575 let type_name = resource.type_name();
576 let debug_value = crate::TypedValue {
577 r#type: type_name,
578 value,
579 };
580
581 debug_map.key(&k);
582 debug_map.value(&debug_value);
583 });
584
585 debug_map.finish()
586 }
587}
588
589impl<K, BoxDT, ValueT> Debug for TypeMap<K, BoxDT, UnknownEntriesSome<ValueT>>
590where
591 K: Eq + Hash + Debug,
592 BoxDT: DataTypeWrapper,
593 ValueT: Clone + Debug + PartialEq + Eq,
594{
595 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
596 f.debug_struct("TypeMap")
597 .field("inner", &InnerWrapper { inner: &self.inner })
598 .field("unknown_entries", &self.unknown_entries)
599 .finish()
600 }
601}
602
603#[cfg(test)]
604mod tests {
605 use std::fmt::{self, Write};
606
607 use serde::{Deserialize, Serialize};
608
609 use crate::{
610 common::UnknownEntriesSome,
611 untagged::{BoxDataTypeDowncast, BoxDt, BoxDtDisplay, TypeMap},
612 };
613
614 #[cfg(feature = "ordered")]
615 #[test]
616 fn serialize() {
617 let mut type_map = TypeMap::new();
618 type_map.insert("one", 1u32);
619 type_map.insert("two", 2u64);
620 type_map.insert("three", A(3));
621
622 let serialized =
623 serde_yaml_ng::to_string(&type_map).expect("Failed to serialize `type_map`.");
624 let expected = r#"one: 1
625two: 2
626three: 3
627"#
628 .to_string();
629 assert_eq!(expected, serialized);
630 }
631
632 #[test]
633 fn clone() {
634 let mut type_map = TypeMap::new();
635 type_map.insert("one", A(1));
636
637 let mut type_map_clone = type_map.clone();
638 type_map_clone.insert("one", A(2));
639
640 assert_eq!(Some(A(1)), type_map.get("one").copied());
641 assert_eq!(Some(A(2)), type_map_clone.get("one").copied());
642 }
643
644 #[test]
645 fn clone_with_unknown_entries() {
646 let mut type_map =
647 TypeMap::<_, BoxDt, UnknownEntriesSome<serde_yaml_ng::Value>>::new_typed();
648 type_map.insert("one", A(1));
649 type_map.insert_unknown_entry("two", serde_yaml_ng::Value::Bool(true));
650
651 let mut type_map_clone = type_map.clone();
652 type_map_clone.insert("one", A(2));
653
654 assert_eq!(Some(A(1)), type_map.get("one").copied());
655 assert_eq!(
656 Some(serde_yaml_ng::Value::Bool(true)),
657 type_map.get_unknown_entry("two").cloned()
658 );
659 assert_eq!(Some(A(2)), type_map_clone.get("one").copied());
660 assert_eq!(
661 Some(serde_yaml_ng::Value::Bool(true)),
662 type_map_clone.get_unknown_entry("two").cloned()
663 );
664 }
665
666 #[test]
667 fn into_inner() {
668 let mut type_map = TypeMap::new();
669 type_map.insert("one", A(1));
670
671 let index_map = type_map.into_inner();
672
673 assert!(index_map.contains_key("one"));
674 }
675
676 #[cfg(not(feature = "debug"))]
677 #[test]
678 fn debug() {
679 let mut type_map = TypeMap::new();
680 type_map.insert("one", A(1));
681
682 assert_eq!(
683 "{\"one\": TypedValue { type: \"type_reg::untagged::type_map::tests::A\", value: \"..\" }}",
684 format!("{type_map:?}")
685 );
686 }
687
688 #[cfg(not(feature = "debug"))]
689 #[test]
690 fn debug_with_unknown_entries_some() {
691 let mut type_map = TypeMap::<&'static str, BoxDt, UnknownEntriesSome<()>>::default();
692 type_map.insert("one", A(1));
693
694 assert_eq!(
695 "TypeMap { \
696 inner: {\
697 \"one\": TypedValue { type: \"type_reg::untagged::type_map::tests::A\", value: \"..\" }\
698 }, \
699 unknown_entries: {} \
700 }",
701 format!("{type_map:?}")
702 );
703 }
704
705 #[cfg(feature = "debug")]
706 #[test]
707 fn debug() {
708 let mut type_map = TypeMap::new();
709 type_map.insert("one", A(1));
710
711 assert_eq!(
712 r#"{"one": TypedValue { type: "type_reg::untagged::type_map::tests::A", value: A(1) }}"#,
713 format!("{type_map:?}")
714 );
715 }
716
717 #[cfg(feature = "debug")]
718 #[test]
719 fn debug_with_unknown_entries_some() {
720 let mut type_map = TypeMap::<&'static str, BoxDt, UnknownEntriesSome<()>>::default();
721 type_map.insert("one", A(1));
722
723 assert_eq!(
724 "TypeMap { \
725 inner: {\
726 \"one\": TypedValue { type: \"type_reg::untagged::type_map::tests::A\", value: A(1) }}, \
727 unknown_entries: {} \
728 }",
729 format!("{type_map:?}")
730 );
731 }
732
733 #[test]
734 fn into_inner_unknown_entries_none() {
735 let mut type_map = TypeMap::new();
736 type_map.insert("one", A(1));
737
738 let mut inner = type_map.into_inner();
739 let one = inner
740 .get_mut("one")
741 .and_then(BoxDataTypeDowncast::<A>::downcast_mut)
742 .copied();
743
744 assert_eq!(Some(A(1)), one);
745 }
746
747 #[test]
748 fn into_inner_unknown_entries_some() {
749 let mut type_map = TypeMap::<&'static str, BoxDt, UnknownEntriesSome<()>>::default();
750 type_map.insert("one", A(1));
751
752 let (mut inner, unknown_entries) = type_map.into_inner();
753 let one = inner
754 .get_mut("one")
755 .and_then(BoxDataTypeDowncast::<A>::downcast_mut)
756 .copied();
757
758 assert_eq!(Some(A(1)), one);
759 assert!(unknown_entries.is_empty());
760 }
761
762 #[test]
763 fn get_mut() {
764 let mut type_map = TypeMap::new();
765 type_map.insert("one", A(1));
766 type_map.insert("two", ADisplay(2));
767
768 let one = type_map.get_mut::<A, _>("one").copied();
769 let two = type_map.get_mut::<ADisplay, _>("two").copied();
770 let three = type_map.get_mut::<u32, _>("one").copied();
771
772 assert_eq!(Some(A(1)), one);
773 assert_eq!(Some(ADisplay(2)), two);
774 assert_eq!(None, three);
775 }
776
777 #[test]
778 fn get_raw() {
779 let mut type_map = TypeMap::<&'static str>::new();
780 type_map.insert("one", 1u32);
781 let boxed_one = type_map.get_raw("one");
782
783 let one = boxed_one
784 .and_then(BoxDataTypeDowncast::<u32>::downcast_ref)
785 .copied();
786
787 assert_eq!(Some(1), one);
788 }
789
790 #[test]
791 fn get_raw_mut() {
792 let mut type_map = TypeMap::<&'static str>::new();
793 type_map.insert("one", 1u32);
794
795 let boxed_one = type_map.get_raw_mut("one");
796 let one = boxed_one.and_then(BoxDataTypeDowncast::<u32>::downcast_mut);
797 assert_eq!(Some(1).as_mut(), one);
798
799 if let Some(one) = one {
800 *one += 1;
801 }
802
803 let one_plus_one = type_map.get::<u32, _>("one").copied();
804 assert_eq!(Some(2), one_plus_one);
805 }
806
807 #[test]
808 fn with_capacity() {
809 let type_map = TypeMap::<&str>::default();
810 assert_eq!(0, type_map.capacity());
811
812 let type_map = TypeMap::<&str>::with_capacity(5);
813 assert!(type_map.capacity() >= 5);
814 }
815
816 #[test]
817 fn deref_mut() {
818 let mut type_map = TypeMap::new();
819 type_map.insert("one", A(1));
820
821 if let Some(v) = type_map.values_mut().next() {
822 if let Some(a) = BoxDataTypeDowncast::<A>::downcast_mut(v) {
823 a.0 = 2;
824 }
825 }
826
827 let one = type_map.get::<A, _>("one").copied();
828 assert_eq!(Some(A(2)), one);
829 }
830
831 #[test]
832 fn display() -> fmt::Result {
833 let mut type_map = TypeMap::<_, BoxDtDisplay>::new_typed();
834 type_map.insert("one", ADisplay(1));
835
836 let formatted = type_map
837 .iter()
838 .try_fold(String::with_capacity(64), |mut s, (k, v)| {
839 write!(&mut s, "{k}: {v}")?;
840 Ok(s)
841 })?;
842
843 assert_eq!("one: 1", formatted);
844 Ok(())
845 }
846
847 #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
848 struct A(u32);
849
850 #[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
851 struct ADisplay(u32);
852
853 impl fmt::Display for ADisplay {
854 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
855 self.0.fmt(f)
856 }
857 }
858
859 #[test]
860 fn a_coverage() {
861 let a = Clone::clone(&A(0));
862 assert_eq!("A(0)", format!("{a:?}"));
863 assert!(serde_yaml_ng::to_string(&a).is_ok());
864 assert_eq!(A(0), serde_yaml_ng::from_str("0").unwrap());
865 }
866
867 #[test]
868 fn a_display_coverage() {
869 let a = Clone::clone(&ADisplay(0));
870 assert_eq!("ADisplay(0)", format!("{a:?}"));
871 assert!(serde_yaml_ng::to_string(&a).is_ok());
872 assert_eq!(ADisplay(0), serde_yaml_ng::from_str("0").unwrap());
873 }
874}