type_reg/untagged/
type_map.rs

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/// Map of types that can be serialized / deserialized.
20#[derive(serde::Serialize)]
21#[serde(transparent)]
22pub struct TypeMap<K, BoxDT = BoxDt, UnknownEntriesT = UnknownEntriesNone>
23where
24    K: Eq + Hash,
25    UnknownEntriesT: UnknownEntries,
26{
27    /// Underlying map.
28    inner: Map<K, BoxDT>,
29    /// Unknown entries encountered during deserialization.
30    #[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    // Creates an empty `TypeMap`.
39    ///
40    /// The map is initially created with a capacity of 0, so it will not
41    /// allocate until it is first inserted into.
42    ///
43    /// # Examples
44    ///
45    /// ```rust
46    /// use type_reg::untagged::TypeMap;
47    /// let mut type_map = TypeMap::<&'static str>::new();
48    /// ```
49    pub fn new() -> Self {
50        Self {
51            inner: Map::new(),
52            unknown_entries: Map::new(),
53        }
54    }
55
56    /// Creates an empty `TypeMap` with the specified capacity.
57    ///
58    /// The map will be able to hold at least capacity elements without
59    /// reallocating. If capacity is 0, the map will not allocate.
60    ///
61    /// # Examples
62    ///
63    /// ```rust
64    /// use type_reg::untagged::TypeMap;
65    /// let type_map = TypeMap::<&'static str>::with_capacity(10);
66    /// ```
67    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    /// Returns the underlying map.
81    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    /// Returns the underlying map and unknown entries.
93    pub fn into_inner(self) -> (Map<K, BoxDT>, Map<K, ValueT>) {
94        (self.inner, self.unknown_entries)
95    }
96
97    /// Returns the entries that were unable to be deserialized.
98    ///
99    /// These are the entries from the source data for which no type was
100    /// registered against the [`TypeReg`] used to deserialize that source data.
101    ///
102    /// [`TypeReg`]: crate::untagged::TypeReg
103    pub fn unknown_entries(&self) -> &Map<K, ValueT> {
104        &self.unknown_entries
105    }
106
107    /// Returns a reference to the value corresponding to the key.
108    ///
109    /// The key may be any borrowed form of the map’s key type, but `Hash` and
110    /// `Eq` on the borrowed form must match those for the key type.
111    ///
112    /// If there is an entry, but the data type does not match, `None` is
113    /// returned.
114    ///
115    /// # Examples
116    ///
117    /// ## YAML
118    ///
119    /// ```rust
120    /// use type_reg::untagged::{TypeMap, TypeReg};
121    ///
122    /// let mut type_reg = TypeReg::<String>::new();
123    ///
124    /// let type_map = type_reg
125    ///     .deserialize_map_with_unknowns::<'_, serde_yaml_ng::Value, _, _>(
126    ///         serde_yaml_ng::Deserializer::from_str("one: 1"),
127    ///     )
128    ///     .unwrap();
129    ///
130    /// let one = type_map.get_unknown_entry("one").cloned();
131    ///
132    /// assert_eq!(
133    ///     one,
134    ///     Some(serde_yaml_ng::Value::Number(serde_yaml_ng::Number::from(
135    ///         1u32
136    ///     )))
137    /// );
138    /// assert_eq!(1, type_map.unknown_entries().len());
139    /// ```
140    ///
141    /// ## JSON
142    ///
143    /// ```rust
144    /// use type_reg::untagged::{TypeMap, TypeReg};
145    ///
146    /// let mut type_reg = TypeReg::<String>::new();
147    ///
148    /// let type_map = type_reg
149    ///     .deserialize_map_with_unknowns::<'_, serde_json::Value, _, _>(
150    ///         &mut serde_json::Deserializer::from_str(r#"{ "one": 1 }"#),
151    ///     )
152    ///     .unwrap();
153    ///
154    /// let one = type_map.get_unknown_entry("one").cloned();
155    ///
156    /// assert_eq!(
157    ///     one,
158    ///     Some(serde_json::Value::Number(serde_json::Number::from(1u32)))
159    /// );
160    /// assert_eq!(1, type_map.unknown_entries().len());
161    /// ```
162    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    /// Inserts an unknown entry into the map.
171    ///
172    /// This is only used during deserialization.
173    ///
174    /// If the map did not have this key present, `None` is returned.
175    ///
176    /// If the map did have this key present, the value is updated, and the old
177    /// value is returned. The key is not updated, though; this matters for
178    /// types that can be `==` without being identical.
179    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    // Creates an empty `TypeMap`.
191    ///
192    /// The map is initially created with a capacity of 0, so it will not
193    /// allocate until it is first inserted into.
194    ///
195    /// # Examples
196    ///
197    /// ```rust
198    /// use type_reg::untagged::TypeMap;
199    /// let mut type_map = TypeMap::<&'static str>::new();
200    /// ```
201    pub fn new_typed() -> Self {
202        Self {
203            inner: Map::new(),
204            unknown_entries: Map::new(),
205        }
206    }
207
208    /// Creates an empty `TypeMap` with the specified capacity.
209    ///
210    /// The map will be able to hold at least capacity elements without
211    /// reallocating. If capacity is 0, the map will not allocate.
212    ///
213    /// # Examples
214    ///
215    /// ```rust
216    /// use type_reg::untagged::TypeMap;
217    /// let type_map = TypeMap::<&'static str>::with_capacity(10);
218    /// ```
219    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    /// Returns a reference to the value corresponding to the key.
227    ///
228    /// The key may be any borrowed form of the map’s key type, but `Hash` and
229    /// `Eq` on the borrowed form must match those for the key type.
230    ///
231    /// If there is an entry, but the data type does not match, `None` is
232    /// returned.
233    ///
234    /// # Examples
235    ///
236    /// ```rust
237    /// use type_reg::untagged::TypeMap;
238    ///
239    /// let mut type_map = TypeMap::<&'static str>::new();
240    /// type_map.insert("one", 1u32);
241    ///
242    /// let one = type_map.get::<u32, _>("one").copied();
243    /// assert_eq!(Some(1), one);
244    /// ```
245    #[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    /// Returns a reference to the value corresponding to the key.
259    ///
260    /// The key may be any borrowed form of the map’s key type, but `Hash` and
261    /// `Eq` on the borrowed form must match those for the key type.
262    ///
263    /// If there is an entry, but the data type does not match, `None` is
264    /// returned.
265    ///
266    /// # Examples
267    ///
268    /// ```rust
269    /// use type_reg::untagged::TypeMap;
270    ///
271    /// let mut type_map = TypeMap::<&'static str>::new();
272    /// type_map.insert("one", 1u32);
273    ///
274    /// let one = type_map.get::<u32, _>("one").copied();
275    /// assert_eq!(Some(1), one);
276    /// ```
277    #[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    /// Returns a mutable reference to the value corresponding to the key.
291    ///
292    /// The key may be any borrowed form of the map’s key type, but `Hash` and
293    /// `Eq` on the borrowed form must match those for the key type.
294    ///
295    /// If there is an entry, but the data type does not match, `None` is
296    /// returned.
297    ///
298    /// # Examples
299    ///
300    /// ```rust
301    /// use type_reg::untagged::TypeMap;
302    ///
303    /// let mut type_map = TypeMap::<&'static str>::new();
304    /// type_map.insert("one", 1u32);
305    ///
306    /// let mut one = type_map.get_mut::<u32, _>("one");
307    /// one.as_mut().map(|n| **n += 1);
308    /// assert_eq!(Some(2), one.copied());
309    /// ```
310    #[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    /// Returns a mutable reference to the value corresponding to the key.
324    ///
325    /// The key may be any borrowed form of the map’s key type, but `Hash` and
326    /// `Eq` on the borrowed form must match those for the key type.
327    ///
328    /// If there is an entry, but the data type does not match, `None` is
329    /// returned.
330    ///
331    /// # Examples
332    ///
333    /// ```rust
334    /// use type_reg::untagged::TypeMap;
335    ///
336    /// let mut type_map = TypeMap::<&'static str>::new();
337    /// type_map.insert("one", 1u32);
338    ///
339    /// let mut one = type_map.get_mut::<u32, _>("one");
340    /// one.as_mut().map(|n| **n += 1);
341    /// assert_eq!(Some(2), one.copied());
342    #[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    /// Returns a reference to the boxed value corresponding to the key.
356    ///
357    /// The key may be any borrowed form of the map’s key type, but `Hash` and
358    /// `Eq` on the borrowed form must match those for the key type.
359    ///
360    /// If there is an entry, but the data type does not match, `None` is
361    /// returned.
362    ///
363    /// # Examples
364    ///
365    /// ```rust
366    /// use type_reg::untagged::{BoxDataTypeDowncast, TypeMap};
367    ///
368    /// let mut type_map = TypeMap::<&'static str>::new();
369    /// type_map.insert("one", 1u32);
370    ///
371    /// let boxed_one = type_map.get_raw("one");
372    /// let one = boxed_one
373    ///     .and_then(|boxed_one| BoxDataTypeDowncast::<u32>::downcast_ref(boxed_one))
374    ///     .copied();
375    /// assert_eq!(Some(1), one);
376    /// ```
377    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    /// Returns a mutable reference to the boxed value corresponding to the key.
386    ///
387    /// The key may be any borrowed form of the map’s key type, but `Hash` and
388    /// `Eq` on the borrowed form must match those for the key type.
389    ///
390    /// If there is an entry, but the data type does not match, `None` is
391    /// returned.
392    ///
393    /// # Examples
394    ///
395    /// ```rust
396    /// use type_reg::untagged::{BoxDataTypeDowncast, TypeMap};
397    ///
398    /// let mut type_map = TypeMap::<&'static str>::new();
399    /// type_map.insert("one", 1u32);
400    ///
401    /// let boxed_one = type_map.get_raw_mut("one");
402    /// let one = boxed_one.and_then(|boxed_one| BoxDataTypeDowncast::<u32>::downcast_mut(boxed_one));
403    /// assert_eq!(Some(1).as_mut(), one);
404    ///
405    /// if let Some(one) = one {
406    ///     *one += 1;
407    /// }
408    ///
409    /// let one_plus_one = type_map.get::<u32, _>("one").copied();
410    /// assert_eq!(Some(2), one_plus_one);
411    /// ```
412    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    /// Inserts a key-value pair into the map.
421    ///
422    /// If the map did not have this key present, `None` is returned.
423    ///
424    /// If the map did have this key present, the value is updated, and the old
425    /// value is returned. The key is not updated, though; this matters for
426    /// types that can be `==` without being identical.
427    #[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    /// Inserts a key-value pair into the map.
436    ///
437    /// If the map did not have this key present, `None` is returned.
438    ///
439    /// If the map did have this key present, the value is updated, and the old
440    /// value is returned. The key is not updated, though; this matters for
441    /// types that can be `==` without being identical.
442    #[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    /// Inserts a key-value pair into the map.
451    ///
452    /// If the map did not have this key present, `None` is returned.
453    ///
454    /// If the map did have this key present, the value is updated, and the old
455    /// value is returned. The key is not updated, though; this matters for
456    /// types that can be `==` without being identical.
457    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            // At runtime, we are unable to determine if the resource is `Debug`.
531            #[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            // At runtime, we are unable to determine if the resource is `Debug`.
569            #[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}