musli_core/hint/
map_hint.rs

1use crate::Context;
2use crate::de::SizeHint;
3
4mod sealed {
5    pub trait Sealed {}
6    impl<T, M> Sealed for crate::__priv::EncodeMapHint<'_, T, M> where T: ?Sized {}
7    impl Sealed for usize {}
8    impl Sealed for Option<usize> {}
9}
10
11/// A size hint passed in when encoding or decoding a map.
12///
13/// # Examples
14///
15/// ```
16/// use musli_core::hint::MapHint;
17///
18/// fn get_map_size<H>(hint: H) -> Option<usize>
19/// where
20///     H: MapHint,
21/// {
22///     hint.get()
23/// }
24///
25/// // Known size hint
26/// let size = get_map_size(5usize);
27/// assert_eq!(size, Some(5));
28///
29/// // Optional size hint with value
30/// let size = get_map_size(Some(3usize));
31/// assert_eq!(size, Some(3));
32///
33/// // Optional size hint without value
34/// let size = get_map_size(None::<usize>);
35/// assert_eq!(size, None);
36/// ```
37pub trait MapHint: Sized + self::sealed::Sealed {
38    /// Get an optional map hint.
39    fn get(self) -> Option<usize>;
40
41    /// Require a map hint or raise an error indicating that the format doesn't
42    /// support maps of unknown size if one is not present.
43    #[inline]
44    fn require<C>(self, cx: C) -> Result<usize, C::Error>
45    where
46        C: Context,
47    {
48        let Some(size) = self.get() else {
49            return Err(cx.message("Format cannot handle maps with an unknown number of entries"));
50        };
51
52        Ok(size)
53    }
54
55    /// Coerce into a [`SizeHint`].
56    #[inline]
57    fn size_hint(self) -> SizeHint {
58        match self.get() {
59            Some(size) => SizeHint::exact(size),
60            None => SizeHint::any(),
61        }
62    }
63}
64
65impl MapHint for usize {
66    #[inline]
67    fn get(self) -> Option<usize> {
68        Some(self)
69    }
70
71    #[inline]
72    fn require<C>(self, _: C) -> Result<usize, C::Error>
73    where
74        C: Context,
75    {
76        Ok(self)
77    }
78
79    #[inline]
80    fn size_hint(self) -> SizeHint {
81        SizeHint::exact(self)
82    }
83}
84
85impl MapHint for Option<usize> {
86    #[inline]
87    fn get(self) -> Option<usize> {
88        self
89    }
90}