musli_core/hint/
sequence_hint.rs

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