musli_core/de/
size_hint.rs

1use core::fmt;
2
3#[derive(Default, Debug, Clone, Copy)]
4enum SizeHintKind {
5    /// The length isn't known.
6    #[default]
7    Any,
8    /// The length is exactly known.
9    Exact(usize),
10}
11
12/// A length hint.
13#[derive(Default, Debug, Clone, Copy)]
14#[non_exhaustive]
15#[doc(hidden)]
16pub struct SizeHint {
17    kind: SizeHintKind,
18}
19
20impl SizeHint {
21    /// Construct a size hint of unknown size.
22    ///
23    /// # Examples
24    ///
25    /// ```
26    /// use musli::de::SizeHint;
27    ///
28    /// let hint = SizeHint::any();
29    /// assert_eq!(hint.or_default(), 0);
30    /// ```
31    #[inline]
32    pub const fn any() -> Self {
33        SizeHint {
34            kind: SizeHintKind::Any,
35        }
36    }
37
38    /// Construct an exactly sized hint.
39    ///
40    /// # Examples
41    ///
42    /// ```
43    /// use musli::de::SizeHint;
44    ///
45    /// let hint = SizeHint::exact(16);
46    /// assert_eq!(hint.or_default(), 16);
47    /// ```
48    #[inline]
49    pub const fn exact(length: usize) -> Self {
50        SizeHint {
51            kind: SizeHintKind::Exact(length),
52        }
53    }
54
55    /// Get a size hint or a default value.
56    ///
57    /// # Examples
58    ///
59    /// ```
60    /// use musli::de::SizeHint;
61    ///
62    /// let hint = SizeHint::any();
63    /// assert_eq!(hint.or_default(), 0);
64    /// ```
65    #[inline]
66    pub fn or_default(self) -> usize {
67        match self.kind {
68            SizeHintKind::Any => 0,
69            SizeHintKind::Exact(n) => n,
70        }
71    }
72}
73
74impl From<Option<usize>> for SizeHint {
75    #[inline]
76    fn from(value: Option<usize>) -> Self {
77        let kind = match value {
78            Some(n) => SizeHintKind::Exact(n),
79            None => SizeHintKind::Any,
80        };
81
82        SizeHint { kind }
83    }
84}
85
86impl fmt::Display for SizeHint {
87    #[inline]
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        match self.kind {
90            SizeHintKind::Any => write!(f, "unknown length"),
91            SizeHintKind::Exact(length) => write!(f, "size {length}"),
92        }
93    }
94}
95
96impl SizeHint {
97    /// Coerce into an `Option`.
98    #[inline]
99    pub fn into_option(self) -> Option<usize> {
100        match self.kind {
101            SizeHintKind::Any => None,
102            SizeHintKind::Exact(len) => Some(len),
103        }
104    }
105}