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}