tinycbor/
primitive.rs

1//! Primitive types.
2use core::fmt::{Display, Formatter};
3
4use crate::{CborLen, Decode, Decoder, Encode, Encoder, EndOfInput, InvalidHeader, SIMPLE, Write};
5
6/// Errors that can occur when encoding or decoding CBOR primitive types.
7#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Error {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Error::EndOfInput(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "EndOfInput", &__self_0),
            Error::InvalidHeader(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "InvalidHeader", &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Error {
    #[inline]
    fn clone(&self) -> Error {
        let _: ::core::clone::AssertParamIsClone<EndOfInput>;
        let _: ::core::clone::AssertParamIsClone<InvalidHeader>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Error { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Error {
    #[inline]
    fn eq(&self, other: &Error) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (Error::EndOfInput(__self_0), Error::EndOfInput(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (Error::InvalidHeader(__self_0),
                    Error::InvalidHeader(__arg1_0)) => __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Error {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<EndOfInput>;
        let _: ::core::cmp::AssertParamIsEq<InvalidHeader>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Error {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            Error::EndOfInput(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            Error::InvalidHeader(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash)]
8pub enum Error {
9    /// The input ended unexpectedly.
10    EndOfInput(EndOfInput),
11    /// The header found did not match the expected header.
12    InvalidHeader(InvalidHeader),
13}
14
15impl core::fmt::Display for Error {
16    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
17        match self {
18            Error::EndOfInput(e) => f.write_fmt(format_args!("{0}", e))write!(f, "{e}"),
19            Error::InvalidHeader(e) => f.write_fmt(format_args!("{0}", e))write!(f, "{e}"),
20        }
21    }
22}
23
24impl From<EndOfInput> for Error {
25    fn from(e: EndOfInput) -> Self {
26        Error::EndOfInput(e)
27    }
28}
29
30impl core::error::Error for Error {
31    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
32        match self {
33            Error::EndOfInput(e) => Some(e),
34            Error::InvalidHeader(e) => Some(e),
35        }
36    }
37}
38
39/// CBOR null type.
40#[derive(#[automatically_derived]
impl ::core::clone::Clone for Null {
    #[inline]
    fn clone(&self) -> Null { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Null { }Copy, #[automatically_derived]
impl ::core::default::Default for Null {
    #[inline]
    fn default() -> Null { Null {} }
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for Null {
    #[inline]
    fn eq(&self, other: &Null) -> bool { true }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Null {
    #[inline]
    fn partial_cmp(&self, other: &Null)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ordering::Equal)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for Null {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {}
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for Null {
    #[inline]
    fn cmp(&self, other: &Null) -> ::core::cmp::Ordering {
        ::core::cmp::Ordering::Equal
    }
}Ord, #[automatically_derived]
impl ::core::fmt::Debug for Null {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Null")
    }
}Debug, #[automatically_derived]
impl ::core::hash::Hash for Null {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {}
}Hash)]
41pub struct Null;
42
43impl Display for Null {
44    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
45        f.write_str("null")
46    }
47}
48
49impl Decode<'_> for Null {
50    type Error = Error;
51
52    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
53        match d.read()? {
54            0xf6 => Ok(Null),
55            _ => Err(Error::InvalidHeader(InvalidHeader)),
56        }
57    }
58}
59
60impl Encode for Null {
61    fn encode<W: Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
62        e.put(&[0xf6])
63    }
64}
65
66impl CborLen for Null {
67    fn cbor_len(&self) -> usize {
68        1
69    }
70}
71
72/// CBOR undefined type.
73#[derive(#[automatically_derived]
impl ::core::clone::Clone for Undefined {
    #[inline]
    fn clone(&self) -> Undefined { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Undefined { }Copy, #[automatically_derived]
impl ::core::default::Default for Undefined {
    #[inline]
    fn default() -> Undefined { Undefined {} }
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for Undefined {
    #[inline]
    fn eq(&self, other: &Undefined) -> bool { true }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Undefined {
    #[inline]
    fn partial_cmp(&self, other: &Undefined)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ordering::Equal)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Eq for Undefined {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {}
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for Undefined {
    #[inline]
    fn cmp(&self, other: &Undefined) -> ::core::cmp::Ordering {
        ::core::cmp::Ordering::Equal
    }
}Ord, #[automatically_derived]
impl ::core::fmt::Debug for Undefined {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "Undefined")
    }
}Debug, #[automatically_derived]
impl ::core::hash::Hash for Undefined {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {}
}Hash)]
74pub struct Undefined;
75
76impl Display for Undefined {
77    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
78        f.write_str("undefined")
79    }
80}
81
82impl Decode<'_> for Undefined {
83    type Error = Error;
84
85    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
86        match d.read()? {
87            0xf7 => Ok(Undefined),
88            _ => Err(Error::InvalidHeader(InvalidHeader)),
89        }
90    }
91}
92
93impl Encode for Undefined {
94    fn encode<W: Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
95        e.put(&[0xf7])
96    }
97}
98
99impl CborLen for Undefined {
100    fn cbor_len(&self) -> usize {
101        1
102    }
103}
104
105/// A CBOR simple value.
106#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Simple {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Simple",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Simple {
    #[inline]
    fn clone(&self) -> Simple {
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Simple { }Copy, #[automatically_derived]
impl ::core::default::Default for Simple {
    #[inline]
    fn default() -> Simple { Simple(::core::default::Default::default()) }
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for Simple {
    #[inline]
    fn eq(&self, other: &Simple) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Simple {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<u8>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Simple {
    #[inline]
    fn partial_cmp(&self, other: &Simple)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Simple {
    #[inline]
    fn cmp(&self, other: &Simple) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Simple {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash)]
107pub struct Simple(u8);
108
109impl TryFrom<u8> for Simple {
110    type Error = InvalidHeader;
111
112    fn try_from(value: u8) -> Result<Self, Self::Error> {
113        if !(20..32).contains(&value) {
114            Ok(Simple(value))
115        } else {
116            Err(InvalidHeader)
117        }
118    }
119}
120
121impl Display for Simple {
122    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
123        f.write_fmt(format_args!("simple({0})", self.0))write!(f, "simple({})", self.0)
124    }
125}
126
127impl Decode<'_> for Simple {
128    type Error = Error;
129
130    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
131        match d.read()? {
132            n @ SIMPLE..=0xf3 => Ok(Simple(n - SIMPLE)),
133            0xf8 => {
134                let byte = d.read()?;
135                if byte < 0x20 {
136                    return Err(Error::InvalidHeader(InvalidHeader));
137                }
138                Ok(Simple(byte))
139            }
140            _ => Err(Error::InvalidHeader(InvalidHeader)),
141        }
142    }
143}
144
145impl Encode for Simple {
146    fn encode<W: Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
147        if self.0 < 24 {
148            e.put(&[SIMPLE | self.0])
149        } else {
150            e.put(&[SIMPLE | 24])?;
151            e.put(&[self.0])
152        }
153    }
154}
155
156impl CborLen for Simple {
157    fn cbor_len(&self) -> usize {
158        if self.0 < 24 { 1 } else { 2 }
159    }
160}
161
162impl Decode<'_> for bool {
163    type Error = Error;
164
165    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
166        match d.read()? {
167            0xf4 => Ok(false),
168            0xf5 => Ok(true),
169            _ => Err(Error::InvalidHeader(InvalidHeader)),
170        }
171    }
172}
173
174impl Encode for bool {
175    fn encode<W: Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
176        e.put(&[SIMPLE | if *self { 0x15 } else { 0x14 }])
177    }
178}
179
180impl CborLen for bool {
181    fn cbor_len(&self) -> usize {
182        1
183    }
184}
185
186#[cfg(test)]
187mod tests {
188    use super::*;
189    use crate::test;
190
191    #[test]
192    fn null() {
193        assert!(test(Null, &[0xf6]).unwrap());
194    }
195
196    #[test]
197    fn undefined() {
198        assert!(test(Undefined, &[0xf7]).unwrap());
199    }
200
201    #[test]
202    fn simple() {
203        assert!(test(Simple(0), &[0xe0]).unwrap());
204        assert!(test(Simple(19), &[0xf3]).unwrap());
205        assert!(test(Simple(32), &[0xf8, 0x20]).unwrap());
206        assert!(test(Simple(255), &[0xf8, 0xff]).unwrap());
207    }
208
209    #[test]
210    fn bool() {
211        assert!(test(false, &[0xf4]).unwrap());
212        assert!(test(true, &[0xf5]).unwrap());
213    }
214}