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    pub fn or_default(self) -> usize {
66        match self.kind {
67            SizeHintKind::Any => 0,
68            SizeHintKind::Exact(n) => n,
69        }
70    }
71}
72
73impl From<Option<usize>> for SizeHint {
74    fn from(value: Option<usize>) -> Self {
75        let kind = match value {
76            Some(n) => SizeHintKind::Exact(n),
77            None => SizeHintKind::Any,
78        };
79
80        SizeHint { kind }
81    }
82}
83
84impl fmt::Display for SizeHint {
85    #[inline]
86    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87        match self.kind {
88            SizeHintKind::Any => write!(f, "unknown length"),
89            SizeHintKind::Exact(length) => write!(f, "{length} items"),
90        }
91    }
92}
93
94impl SizeHint {
95    /// Coerce into an `Option`.
96    pub fn into_option(self) -> Option<usize> {
97        match self.kind {
98            SizeHintKind::Any => None,
99            SizeHintKind::Exact(len) => Some(len),
100        }
101    }
102}