musli_core/hint/sequence_hint.rs
1use crate::de::SizeHint;
2use crate::Context;
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.
11pub trait SequenceHint: Sized + self::sealed::Sealed {
12    /// Get an optional sequence hint.
13    fn get(self) -> Option<usize>;
14
15    /// Require a sequence hint or raise an error indicating that the format
16    /// doesn't support sequences of unknown size if one is not present.
17    #[inline]
18    fn require<C>(self, cx: C) -> Result<usize, C::Error>
19    where
20        C: Context,
21    {
22        let Some(size) = self.get() else {
23            return Err(
24                cx.message("Format cannot handle sequences with an unknown number of items")
25            );
26        };
27
28        Ok(size)
29    }
30
31    /// Coerce into a [`SizeHint`].
32    #[inline]
33    fn size_hint(self) -> SizeHint {
34        match self.get() {
35            Some(size) => SizeHint::exact(size),
36            None => SizeHint::any(),
37        }
38    }
39}
40
41impl SequenceHint for usize {
42    #[inline]
43    fn get(self) -> Option<usize> {
44        Some(self)
45    }
46
47    #[inline]
48    fn require<C>(self, _: C) -> Result<usize, C::Error>
49    where
50        C: Context,
51    {
52        Ok(self)
53    }
54
55    #[inline]
56    fn size_hint(self) -> SizeHint {
57        SizeHint::exact(self)
58    }
59}
60
61impl SequenceHint for Option<usize> {
62    #[inline]
63    fn get(self) -> Option<usize> {
64        self
65    }
66}