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