Skip to main content

cbor_core/
simple_value.rs

1use crate::{DataType, Error, Result};
2
3/// A CBOR simple value (major type 7, values 0-23 and 32-255).
4///
5/// In CBOR, booleans and null are not separate types but specific simple
6/// values: `false` is 20, `true` is 21, `null` is 22. The constants
7/// [`FALSE`](Self::FALSE), [`TRUE`](Self::TRUE), and [`NULL`](Self::NULL)
8/// are provided for these. Values 24-31 are reserved by the CBOR
9/// specification and cannot be constructed. Note that CBOR also defines
10/// `undefined` (simple value 23), but CBOR::Core does not give it any
11/// special treatment.
12#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
13#[repr(transparent)]
14pub struct SimpleValue(pub(crate) u8);
15
16impl SimpleValue {
17    /// CBOR `false` (simple value 20).
18    pub const FALSE: Self = SimpleValue(20);
19    /// CBOR `true` (simple value 21).
20    pub const TRUE: Self = SimpleValue(21);
21    /// CBOR `null` (simple value 22).
22    pub const NULL: Self = SimpleValue(22);
23
24    /// Create a simple value from any type that implements `TryInto<SimpleValue>`.
25    ///
26    /// This is a convenience wrapper around `TryInto` that unwraps the result.
27    ///
28    /// # Panics
29    ///
30    /// Panics if `value` is in the reserved range 24-31. Use [`from_u8`](Self::from_u8)
31    /// for a fallible alternative.
32    pub fn new(value: impl TryInto<Self, Error = Error>) -> Self {
33        value.try_into().unwrap()
34    }
35
36    /// Create a simple value from a raw number. Returns `Err` for
37    /// reserved values 24-31.
38    pub const fn from_u8(value: u8) -> Result<Self> {
39        let valid_range = value <= 23 || value >= 32;
40        if valid_range {
41            Ok(Self(value))
42        } else {
43            Err(Error::InvalidSimpleValue)
44        }
45    }
46
47    #[inline]
48    #[must_use]
49    /// Create from a boolean.
50    pub const fn from_bool(value: bool) -> Self {
51        if value { Self::TRUE } else { Self::FALSE }
52    }
53
54    #[inline]
55    #[must_use]
56    /// Return the [`DataType`] of this simple value.
57    pub const fn data_type(&self) -> DataType {
58        match self.0 {
59            20 | 21 => DataType::Bool,
60            22 => DataType::Null,
61            _ => DataType::Simple,
62        }
63    }
64
65    /// Convert to `bool`. Returns `Err` for non-boolean simple values.
66    pub const fn to_bool(&self) -> Result<bool> {
67        match *self {
68            Self::FALSE => Ok(false),
69            Self::TRUE => Ok(true),
70            _ => Err(Error::InvalidSimpleValue),
71        }
72    }
73
74    /// Return the raw simple value number.
75    #[must_use]
76    pub const fn to_u8(&self) -> u8 {
77        self.0
78    }
79}
80
81impl TryFrom<u8> for SimpleValue {
82    type Error = Error;
83
84    #[inline]
85    fn try_from(value: u8) -> std::result::Result<Self, Self::Error> {
86        Self::from_u8(value)
87    }
88}
89
90impl From<SimpleValue> for u8 {
91    #[inline]
92    fn from(value: SimpleValue) -> Self {
93        value.to_u8()
94    }
95}
96
97impl From<bool> for SimpleValue {
98    #[inline]
99    fn from(value: bool) -> Self {
100        Self::from_bool(value)
101    }
102}
103
104impl TryFrom<SimpleValue> for bool {
105    type Error = Error;
106
107    fn try_from(value: SimpleValue) -> std::result::Result<Self, Self::Error> {
108        value.to_bool()
109    }
110}
111
112impl From<()> for SimpleValue {
113    #[inline]
114    fn from(_: ()) -> Self {
115        Self::NULL
116    }
117}