Skip to main content

tinycbor/
num.rs

1//! Numeric types.
2use crate::{
3    CborLen, Decode, Decoder, Encode, Encoder, EndOfInput, InvalidHeader, SIGNED, SIMPLE, primitive,
4};
5
6pub mod nonzero;
7
8/// Possible errors when decoding numbers.
9#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Error {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Error::Malformed(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Malformed", &__self_0),
            Error::Narrowing =>
                ::core::fmt::Formatter::write_str(f, "Narrowing"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Error {
    #[inline]
    fn clone(&self) -> Error {
        let _: ::core::clone::AssertParamIsClone<primitive::Error>;
        *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::Malformed(__self_0), Error::Malformed(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Error {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<primitive::Error>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Error {
    #[inline]
    fn partial_cmp(&self, other: &Error)
        -> ::core::option::Option<::core::cmp::Ordering> {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match (self, other) {
            (Error::Malformed(__self_0), Error::Malformed(__arg1_0)) =>
                ::core::cmp::PartialOrd::partial_cmp(__self_0, __arg1_0),
            _ =>
                ::core::cmp::PartialOrd::partial_cmp(&__self_discr,
                    &__arg1_discr),
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Error {
    #[inline]
    fn cmp(&self, other: &Error) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        match ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr) {
            ::core::cmp::Ordering::Equal =>
                match (self, other) {
                    (Error::Malformed(__self_0), Error::Malformed(__arg1_0)) =>
                        ::core::cmp::Ord::cmp(__self_0, __arg1_0),
                    _ => ::core::cmp::Ordering::Equal,
                },
            cmp => cmp,
        }
    }
}Ord, #[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::Malformed(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash)]
10pub enum Error {
11    /// Number is malformed.
12    Malformed(primitive::Error),
13    /// Number could not be represented without overflow or precision loss.
14    Narrowing,
15}
16
17impl core::fmt::Display for Error {
18    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19        match self {
20            Error::Malformed(_) => f.write_fmt(format_args!("malformed number"))write!(f, "malformed number"),
21            Error::Narrowing => f.write_fmt(format_args!("overflow or precision loss"))write!(f, "overflow or precision loss"),
22        }
23    }
24}
25
26impl From<primitive::Error> for Error {
27    fn from(e: primitive::Error) -> Self {
28        Error::Malformed(e)
29    }
30}
31
32impl From<EndOfInput> for Error {
33    fn from(e: EndOfInput) -> Self {
34        Error::Malformed(primitive::Error::from(e))
35    }
36}
37
38impl From<InvalidHeader> for Error {
39    fn from(e: InvalidHeader) -> Self {
40        Error::Malformed(primitive::Error::from(e))
41    }
42}
43
44impl core::error::Error for Error {
45    fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
46        match self {
47            Error::Malformed(e) => Some(e),
48            Error::Narrowing => None,
49        }
50    }
51}
52
53/// CBOR integer type that covers values of [-2<sup>64</sup>, 2<sup>64</sup> - 1]
54///
55/// CBOR integers keep the sign bit in the major type so there is one extra bit
56/// available for signed numbers compared to Rust's integer types. This type can
57/// be used to encode and decode the full CBOR integer range.
58#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Int {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "Int",
            "negative", &self.negative, "bits", &&self.bits)
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for Int { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Int {
    #[inline]
    fn clone(&self) -> Int {
        let _: ::core::clone::AssertParamIsClone<bool>;
        let _: ::core::clone::AssertParamIsClone<u64>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::default::Default for Int {
    #[inline]
    fn default() -> Int {
        Int {
            negative: ::core::default::Default::default(),
            bits: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for Int {
    #[inline]
    fn eq(&self, other: &Int) -> bool {
        self.negative == other.negative && self.bits == other.bits
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Int {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<bool>;
        let _: ::core::cmp::AssertParamIsEq<u64>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Int {
    #[inline]
    fn partial_cmp(&self, other: &Int)
        -> ::core::option::Option<::core::cmp::Ordering> {
        match ::core::cmp::PartialOrd::partial_cmp(&self.negative,
                &other.negative) {
            ::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
                ::core::cmp::PartialOrd::partial_cmp(&self.bits, &other.bits),
            cmp => cmp,
        }
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for Int {
    #[inline]
    fn cmp(&self, other: &Int) -> ::core::cmp::Ordering {
        match ::core::cmp::Ord::cmp(&self.negative, &other.negative) {
            ::core::cmp::Ordering::Equal =>
                ::core::cmp::Ord::cmp(&self.bits, &other.bits),
            cmp => cmp,
        }
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for Int {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.negative, state);
        ::core::hash::Hash::hash(&self.bits, state)
    }
}Hash)]
59pub struct Int {
60    /// `true` if the integer is negative.
61    pub negative: bool,
62    /// The bits of the integer.
63    ///
64    /// This is the value of the integer for positive integers, and the absolute value minus one
65    /// for negative integers.
66    pub bits: u64,
67}
68
69impl core::fmt::Display for Int {
70    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
71        f.write_fmt(format_args!("{0}", i128::from(*self)))write!(f, "{}", i128::from(*self))
72    }
73}
74
75impl From<u8> for Int {
76    fn from(i: u8) -> Self {
77        Int::from(u64::from(i))
78    }
79}
80
81impl From<u16> for Int {
82    fn from(i: u16) -> Self {
83        Int::from(u64::from(i))
84    }
85}
86
87impl From<u32> for Int {
88    fn from(i: u32) -> Self {
89        Int::from(u64::from(i))
90    }
91}
92
93impl From<u64> for Int {
94    fn from(i: u64) -> Self {
95        Int {
96            negative: false,
97            bits: i,
98        }
99    }
100}
101
102impl From<usize> for Int {
103    fn from(i: usize) -> Self {
104        Int::from(i as u64)
105    }
106}
107
108impl From<i8> for Int {
109    fn from(i: i8) -> Self {
110        Int::from(i64::from(i))
111    }
112}
113
114impl From<i16> for Int {
115    fn from(i: i16) -> Self {
116        Int::from(i64::from(i))
117    }
118}
119
120impl From<i32> for Int {
121    fn from(i: i32) -> Self {
122        Int::from(i64::from(i))
123    }
124}
125
126impl From<i64> for Int {
127    fn from(i: i64) -> Self {
128        if i.is_negative() {
129            Int {
130                negative: true,
131                bits: (-1 - i) as u64,
132            }
133        } else {
134            Int {
135                negative: false,
136                bits: i as u64,
137            }
138        }
139    }
140}
141
142impl From<isize> for Int {
143    fn from(i: isize) -> Self {
144        Int::from(i64::try_from(i).unwrap())
145    }
146}
147
148impl From<Int> for i128 {
149    fn from(i: Int) -> Self {
150        let j = i128::from(i.bits);
151        if i.negative { -1 - j } else { j }
152    }
153}
154
155impl Decode<'_> for Int {
156    type Error = primitive::Error;
157
158    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
159        Ok(match d.peek()? {
160            0x00..=0x1b => Int {
161                negative: false,
162                bits: u64::decode(d)?,
163            },
164            _ => Int {
165                negative: true,
166                bits: match d.read()? {
167                    n @ 0x20..=0x37 => n as u64 - 0x20,
168                    0x38 => d.read().map(|n| n as u64)?,
169                    0x39 => d.read_array().map(u16::from_be_bytes).map(|n| n as u64)?,
170                    0x3a => d.read_array().map(u32::from_be_bytes).map(|n| n as u64)?,
171                    0x3b => d.read_array().map(u64::from_be_bytes)?,
172                    _ => return Err(InvalidHeader.into()),
173                },
174            },
175        })
176    }
177}
178
179impl Encode for Int {
180    fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
181        if !self.negative {
182            return self.bits.encode(e);
183        }
184        match self.bits {
185            n @ 0..=0x17 => e.put(&[SIGNED | n as u8]),
186            n @ 0x18..=0xff => e.put(&[SIGNED | 24, n as u8]),
187            n @ 0x100..=0xffff => {
188                e.put(&[SIGNED | 25])?;
189                e.put(&(n as u16).to_be_bytes()[..])
190            }
191            n @ 0x1_0000..=0xffff_ffff => {
192                e.put(&[SIGNED | 26])?;
193                e.put(&(n as u32).to_be_bytes()[..])
194            }
195            n => {
196                e.put(&[SIGNED | 27])?;
197                e.put(&n.to_be_bytes()[..])
198            }
199        }
200    }
201}
202
203impl CborLen for Int {
204    fn cbor_len(&self) -> usize {
205        self.bits.cbor_len()
206    }
207}
208
209/// A newtype wrapper to handle `u8` as a CBOR number type.
210///
211/// Because rust does not yet have specialization, a newtype wrapper is needed to encode and decode
212/// `u8` as a number type, rather than as a byte string.
213#[derive(#[automatically_derived]
impl ::core::fmt::Debug for U8 {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "U8", &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for U8 {
    #[inline]
    fn default() -> U8 { U8(::core::default::Default::default()) }
}Default, #[automatically_derived]
impl ::core::marker::Copy for U8 { }Copy, #[automatically_derived]
impl ::core::clone::Clone for U8 {
    #[inline]
    fn clone(&self) -> U8 {
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for U8 {
    #[inline]
    fn eq(&self, other: &U8) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for U8 {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<u8>;
    }
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for U8 {
    #[inline]
    fn partial_cmp(&self, other: &U8)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for U8 {
    #[inline]
    fn cmp(&self, other: &U8) -> ::core::cmp::Ordering {
        ::core::cmp::Ord::cmp(&self.0, &other.0)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for U8 {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash)]
214#[repr(transparent)]
215pub struct U8(pub u8);
216
217impl From<U8> for u8 {
218    fn from(u: U8) -> Self {
219        u.0
220    }
221}
222
223impl From<u8> for U8 {
224    fn from(u: u8) -> Self {
225        U8(u)
226    }
227}
228
229impl From<&u8> for &U8 {
230    fn from(u: &u8) -> Self {
231        // Safety: U8 is #[repr(transparent)] over u8
232        unsafe { &*(u as *const u8 as *const U8) }
233    }
234}
235
236impl AsRef<u8> for U8 {
237    fn as_ref(&self) -> &u8 {
238        &self.0
239    }
240}
241
242impl AsMut<u8> for U8 {
243    fn as_mut(&mut self) -> &mut u8 {
244        &mut self.0
245    }
246}
247
248impl AsRef<U8> for u8 {
249    fn as_ref(&self) -> &U8 {
250        // Safety: U8 is #[repr(transparent)] over u8
251        unsafe { &*(self as *const u8 as *const U8) }
252    }
253}
254
255impl AsMut<U8> for u8 {
256    fn as_mut(&mut self) -> &mut U8 {
257        // Safety: U8 is #[repr(transparent)] over u8
258        unsafe { &mut *(self as *mut u8 as *mut U8) }
259    }
260}
261
262impl Decode<'_> for U8 {
263    type Error = Error;
264    fn decode(d: &mut Decoder<'_>) -> Result<Self, Error> {
265        u64::decode(d)?
266            .try_into()
267            .map(U8)
268            .map_err(|_| Error::Narrowing)
269    }
270}
271
272impl Encode for U8 {
273    fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
274        (self.0 as u64).encode(e)
275    }
276}
277
278impl CborLen for U8 {
279    fn cbor_len(&self) -> usize {
280        (self.0 as u64).cbor_len()
281    }
282}
283
284macro_rules! decode_unsigned {
285    ($t:ident) => {
286        impl<'b> Decode<'b> for $t {
287            type Error = Error;
288            fn decode(d: &mut Decoder<'b>) -> Result<Self, Error> {
289                u64::decode(d)?.try_into().map_err(|_| Error::Narrowing)
290            }
291        }
292    };
293}
294
295macro_rules! encode_unsigned {
296    ($t:ident) => {
297        impl Encode for $t {
298            fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
299                (*self as u64).encode(e)
300            }
301        }
302
303        impl CborLen for $t {
304            fn cbor_len(&self) -> usize {
305                (*self as u64).cbor_len()
306            }
307        }
308    };
309}
310
311macro_rules! impl_unsigned {
312    ($($t:ident)*) => {
313        $(
314            decode_unsigned! { $t }
315
316            encode_unsigned! { $t }
317        )*
318    }
319}
320
321impl<'b> Decode<'b> for u32 {
    type Error = Error;
    fn decode(d: &mut Decoder<'b>) -> Result<Self, Error> {
        u64::decode(d)?.try_into().map_err(|_| Error::Narrowing)
    }
}
impl Encode for u32 {
    fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>)
        -> Result<(), W::Error> {
        (*self as u64).encode(e)
    }
}
impl CborLen for u32 {
    fn cbor_len(&self) -> usize { (*self as u64).cbor_len() }
}impl_unsigned!(u16 u32);
322
323impl Decode<'_> for u64 {
324    type Error = primitive::Error;
325
326    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
327        let value = match d.read()? {
328            n @ 0..=0x17 => Ok(u64::from(n)),
329            0x18 => d.read().map(u64::from),
330            0x19 => d.read_array().map(u16::from_be_bytes).map(u64::from),
331            0x1a => d.read_array().map(u32::from_be_bytes).map(u64::from),
332            0x1b => d.read_array().map(u64::from_be_bytes),
333            _ => return Err(InvalidHeader.into()),
334        }?;
335        Ok(value)
336    }
337}
338
339impl Encode for u64 {
340    fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
341        match self {
342            0..=0x17 => e.put(&[*self as u8]),
343            0x18..=0xff => e.put(&[24, *self as u8]),
344            0x100..=0xffff => {
345                e.put(&[25])?;
346                e.put(&(*self as u16).to_be_bytes()[..])
347            }
348            0x1_0000..=0xffff_ffff => {
349                e.put(&[26])?;
350                e.put(&(*self as u32).to_be_bytes()[..])
351            }
352            _ => {
353                e.put(&[27])?;
354                e.put(&self.to_be_bytes()[..])
355            }
356        }
357    }
358}
359
360impl CborLen for u64 {
361    fn cbor_len(&self) -> usize {
362        match self {
363            0..=0x17 => 1,
364            0x18..=0xff => 2,
365            0x100..=0xffff => 3,
366            0x1_0000..=0xffff_ffff => 5,
367            _ => 9,
368        }
369    }
370}
371
372// if we have a less than 64-bit pointer width, usize may overflow
373#[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))]
374decode_unsigned!(usize);
375
376// If we have 64-bit pointer width, `usize` can be decoded from u64 without overflow.
377#[cfg(target_pointer_width = "64")]
378impl Decode<'_> for usize {
379    type Error = primitive::Error;
380
381    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
382        u64::decode(d).map(|n| n as usize)
383    }
384}
385
386impl Encode for usize {
    fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>)
        -> Result<(), W::Error> {
        (*self as u64).encode(e)
    }
}
impl CborLen for usize {
    fn cbor_len(&self) -> usize { (*self as u64).cbor_len() }
}encode_unsigned!(usize);
387
388impl Decode<'_> for u128 {
389    type Error = primitive::Error;
390
391    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
392        u64::decode(d).map(u128::from)
393    }
394}
395
396macro_rules! impl_signed {
397    ($($t:ident)*) => {
398        $(
399            impl<'b> Decode<'b> for $t {
400                type Error = Error;
401                fn decode(d: &mut Decoder<'b>) -> Result<Self, Error> {
402                    i128::from(crate::num::Int::decode(d)?)
403                        .try_into()
404                        .map_err(|_| Error::Narrowing)
405                }
406            }
407
408            impl Encode for $t {
409                fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
410                    crate::num::Int::from(*self).encode(e)
411                }
412            }
413
414            impl CborLen for $t {
415                fn cbor_len(&self) -> usize {
416                    crate::num::Int::from(*self).cbor_len()
417                }
418            }
419        )*
420    }
421}
422
423impl<'b> Decode<'b> for isize {
    type Error = Error;
    fn decode(d: &mut Decoder<'b>) -> Result<Self, Error> {
        i128::from(crate::num::Int::decode(d)?).try_into().map_err(|_|
                Error::Narrowing)
    }
}
impl Encode for isize {
    fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>)
        -> Result<(), W::Error> {
        crate::num::Int::from(*self).encode(e)
    }
}
impl CborLen for isize {
    fn cbor_len(&self) -> usize { crate::num::Int::from(*self).cbor_len() }
}impl_signed!(i8 i16 i32 i64 isize);
424
425impl Decode<'_> for i128 {
426    type Error = primitive::Error;
427
428    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
429        Int::decode(d).map(i128::from)
430    }
431}
432
433impl Decode<'_> for core::sync::atomic::AtomicBool {
434    type Error = primitive::Error;
435
436    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
437        let value = bool::decode(d)?;
438        Ok(core::sync::atomic::AtomicBool::new(value))
439    }
440}
441
442impl Decode<'_> for core::sync::atomic::AtomicU8 {
443    type Error = Error;
444
445    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
446        let value = U8::decode(d)?.0;
447        Ok(core::sync::atomic::AtomicU8::new(value))
448    }
449}
450
451macro_rules! decode_atomic {
452    ($($prim:ty, $t:ty)*) => {
453        $(
454            impl<'b> Decode<'b> for $t {
455                type Error = <$prim as Decode<'b>>::Error;
456                fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
457                    <$prim>::decode(d).map(<$t>::new)
458                }
459            }
460        )*
461    }
462}
463
464#[cfg(target_has_atomic = "8")]
465impl<'b> Decode<'b> for core::sync::atomic::AtomicI8 {
    type Error = <i8 as Decode<'b>>::Error;
    fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
        <i8>::decode(d).map(<core::sync::atomic::AtomicI8>::new)
    }
}decode_atomic! {
466    i8, core::sync::atomic::AtomicI8
467}
468
469#[cfg(target_has_atomic = "16")]
470impl<'b> Decode<'b> for core::sync::atomic::AtomicI16 {
    type Error = <i16 as Decode<'b>>::Error;
    fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
        <i16>::decode(d).map(<core::sync::atomic::AtomicI16>::new)
    }
}decode_atomic! {
471    u16, core::sync::atomic::AtomicU16
472    i16, core::sync::atomic::AtomicI16
473}
474
475#[cfg(target_has_atomic = "32")]
476impl<'b> Decode<'b> for core::sync::atomic::AtomicI32 {
    type Error = <i32 as Decode<'b>>::Error;
    fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
        <i32>::decode(d).map(<core::sync::atomic::AtomicI32>::new)
    }
}decode_atomic! {
477    u32, core::sync::atomic::AtomicU32
478    i32, core::sync::atomic::AtomicI32
479}
480
481#[cfg(target_has_atomic = "64")]
482impl<'b> Decode<'b> for core::sync::atomic::AtomicI64 {
    type Error = <i64 as Decode<'b>>::Error;
    fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
        <i64>::decode(d).map(<core::sync::atomic::AtomicI64>::new)
    }
}decode_atomic! {
483    u64, core::sync::atomic::AtomicU64
484    i64, core::sync::atomic::AtomicI64
485}
486
487#[cfg(target_has_atomic = "ptr")]
488impl<'b> Decode<'b> for core::sync::atomic::AtomicIsize {
    type Error = <isize as Decode<'b>>::Error;
    fn decode(d: &mut Decoder<'b>) -> Result<Self, Self::Error> {
        <isize>::decode(d).map(<core::sync::atomic::AtomicIsize>::new)
    }
}decode_atomic! {
489    usize, core::sync::atomic::AtomicUsize
490    isize, core::sync::atomic::AtomicIsize
491}
492
493/// Taken from `half` crate https://github.com/VoidStarKat/half-rs/blob/v2.7.1/src/binary16/arch.rs#L685-L729
494const fn f16_to_f32(i: u16) -> f32 {
495    // Check for signed zero
496    if i & 0x7FFFu16 == 0 {
497        return f32::from_bits((i as u32) << 16);
498    }
499
500    let half_sign = (i & 0x8000u16) as u32;
501    let half_exp = (i & 0x7C00u16) as u32;
502    let half_man = (i & 0x03FFu16) as u32;
503
504    // Check for an infinity or NaN when all exponent bits set
505    if half_exp == 0x7C00u32 {
506        // Check for signed infinity if mantissa is zero
507        if half_man == 0 {
508            return f32::from_bits((half_sign << 16) | 0x7F80_0000u32);
509        } else {
510            // NaN, keep current mantissa but also set most significiant mantissa bit
511            return f32::from_bits((half_sign << 16) | 0x7FC0_0000u32 | (half_man << 13));
512        }
513    }
514
515    // Calculate single-precision components with adjusted exponent
516    let sign = half_sign << 16;
517    // Unbias exponent
518    let unbiased_exp = ((half_exp as i32) >> 10) - 15;
519
520    // Check for subnormals, which will be normalized by adjusting exponent
521    if half_exp == 0 {
522        // Calculate how much to adjust the exponent by
523        let e = (half_man as u16).leading_zeros() - 6;
524
525        // Rebias and adjust exponent
526        let exp = (127 - 15 - e) << 23;
527        let man = (half_man << (14 + e)) & 0x7F_FF_FFu32;
528        return f32::from_bits(sign | exp | man);
529    }
530
531    // Rebias exponent for a normalized normal
532    let exp = ((unbiased_exp + 127) as u32) << 23;
533    let man = (half_man & 0x03FFu32) << 13;
534    f32::from_bits(sign | exp | man)
535}
536
537/// Taken from `half` crate https://github.com/VoidStarKat/half-rs/blob/v2.7.1/src/binary16/arch.rs#L556-L614
538///
539/// Modified to also return whether the conversion was lossless.
540const fn f32_to_f16(value: f32) -> (u16, bool) {
541    let x: u32 = value.to_bits();
542
543    // Extract IEEE754 components
544    let sign = x & 0x8000_0000u32;
545    let exp = x & 0x7F80_0000u32;
546    let man = x & 0x007F_FFFFu32;
547
548    // If exp and man are both 0, it is zero.
549    if (x & 0x7FFF_FFFFu32) == 0 {
550        return ((sign >> 16) as u16, true);
551    }
552
553    // Check for all exponent bits being set, which is Infinity or NaN
554    if exp == 0x7F80_0000u32 {
555        // Set mantissa MSB for NaN (and also keep shifted mantissa bits)
556        let nan_bit = if man == 0 { 0 } else { 0x0200u32 };
557        // Lossless if mantissa is zero (infinity)
558        return (
559            ((sign >> 16) | 0x7C00u32 | nan_bit | (man >> 13)) as u16,
560            man == 0,
561        );
562    }
563
564    // The number is normalized, start assembling half precision version
565    let half_sign = sign >> 16;
566    // Unbias the exponent, then bias for half precision
567    let unbiased_exp = ((exp >> 23) as i32) - 127;
568    let half_exp = unbiased_exp + 15;
569
570    // Check for exponent overflow, return +infinity
571    if half_exp >= 0x1F {
572        return ((half_sign | 0x7C00u32) as u16, false);
573    }
574
575    // Check for underflow
576    if half_exp <= 0 {
577        // Check mantissa for what we can do
578        if 14 - half_exp > 24 {
579            // No rounding possibility, so this is a full underflow, return signed zero
580            // Already handled 0 above, so this is not lossless
581            return (half_sign as u16, false);
582        }
583        // Don't forget about hidden leading mantissa bit when assembling mantissa
584        let man = man | 0x0080_0000u32;
585        let shift = 14 - half_exp;
586        let half_man = man >> shift;
587        // Check for lost bits to determine if lossless
588        let lost_mask = (1 << shift) - 1;
589        let is_lossless = (man & lost_mask) == 0;
590
591        // Check for rounding (see comment above functions)
592        let round_bit = 1 << (shift - 1);
593        if (man & round_bit) != 0 && (man & (3 * round_bit - 1)) != 0 {
594            return ((half_sign | (half_man + 1)) as u16, false);
595        }
596        // No exponent for subnormals
597        return ((half_sign | half_man) as u16, is_lossless);
598    }
599
600    // Rebias the exponent
601    let half_exp = (half_exp as u32) << 10;
602    let half_man = man >> 13;
603    // Check for rounding (see comment above functions)
604    let round_bit = 0x0000_1000u32;
605    if (man & round_bit) != 0 && (man & (3 * round_bit - 1)) != 0 {
606        // Round it
607        (((half_sign | half_exp | half_man) + 1) as u16, false)
608    } else {
609        (
610            (half_sign | half_exp | half_man) as u16,
611            (man & 0x1FFF) == 0,
612        )
613    }
614}
615
616impl Decode<'_> for f32 {
617    type Error = Error;
618
619    fn decode(d: &mut Decoder<'_>) -> Result<Self, Self::Error> {
620        Ok(match d.read()? {
621            0xf9 => f16_to_f32(d.read_array().map(u16::from_be_bytes)?),
622            0xfa => f32::from_be_bytes(d.read_array()?),
623            0xfb => {
624                let double = f64::from_be_bytes(d.read_array()?);
625                let narrowed = double as f32;
626                if narrowed as f64 != double {
627                    return Err(Error::Narrowing);
628                }
629                narrowed
630            }
631            _ => {
632                return Err(InvalidHeader.into());
633            }
634        })
635    }
636}
637
638impl Encode for f32 {
639    fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
640        let (half, lossless) = f32_to_f16(*self);
641        if lossless {
642            e.put(&[SIMPLE | 25])?;
643            return e.put(&half.to_be_bytes()[..]);
644        }
645        e.put(&[SIMPLE | 26])?;
646        e.put(&self.to_be_bytes()[..])
647    }
648}
649
650impl CborLen for f32 {
651    fn cbor_len(&self) -> usize {
652        if let (_, true) = f32_to_f16(*self) {
653            3
654        } else {
655            5
656        }
657    }
658}
659
660impl Decode<'_> for f64 {
661    type Error = primitive::Error;
662
663    fn decode(d: &mut Decoder<'_>) -> Result<f64, Self::Error> {
664        match d.read()? {
665            0xf9 => {
666                let half = d.read_array().map(u16::from_be_bytes)?;
667                let float = f16_to_f32(half);
668                Ok(f64::from(float))
669            }
670            0xfa => Ok(f32::from_be_bytes(d.read_array()?).into()),
671            0xfb => Ok(f64::from_be_bytes(d.read_array()?)),
672            _ => Err(InvalidHeader.into()),
673        }
674    }
675}
676
677impl Encode for f64 {
678    fn encode<W: embedded_io::Write>(&self, e: &mut Encoder<W>) -> Result<(), W::Error> {
679        let float = *self as f32;
680        if float as f64 != *self {
681            e.put(&[SIMPLE | 27])?;
682            return e.put(&self.to_be_bytes()[..]);
683        }
684        let (half, lossless) = f32_to_f16(float);
685        if lossless {
686            e.put(&[SIMPLE | 25])?;
687            return e.put(&half.to_be_bytes()[..]);
688        }
689        e.put(&[SIMPLE | 26])?;
690        e.put(&float.to_be_bytes()[..])
691    }
692}
693
694impl CborLen for f64 {
695    fn cbor_len(&self) -> usize {
696        let float = *self as f32;
697        if float as f64 != *self {
698            9
699        } else if let (_, true) = f32_to_f16(float) {
700            3
701        } else {
702            5
703        }
704    }
705}
706
707#[cfg(test)]
708mod tests {
709    use super::*;
710    use crate::{Decode, test};
711
712    #[test]
713    fn u64() {
714        // Values 0-23 should encode in 1 byte
715        assert!(test::<u64>(0, &[0x00]).unwrap());
716        assert!(test::<u64>(1, &[0x01]).unwrap());
717        assert!(test::<u64>(23, &[0x17]).unwrap());
718        // Values 24-255 should encode in 2 bytes
719        assert!(test::<u64>(24, &[0x18, 0x18]).unwrap());
720        assert!(test::<u64>(255, &[0x18, 0xff]).unwrap());
721        // Values 256-65535 should encode in 3 bytes
722        assert!(test::<u64>(256, &[0x19, 0x01, 0x00]).unwrap());
723        assert!(test::<u64>(65535, &[0x19, 0xff, 0xff]).unwrap());
724        // Values 65536-4294967295 should encode in 5 bytes
725        assert!(test::<u64>(65536, &[0x1a, 0x00, 0x01, 0x00, 0x00]).unwrap());
726        assert!(test::<u64>(4294967295, &[0x1a, 0xff, 0xff, 0xff, 0xff]).unwrap());
727        // Values > 4294967295 should encode in 9 bytes
728        assert!(
729            test::<u64>(
730                4294967296,
731                &[0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00]
732            )
733            .unwrap()
734        );
735        assert!(
736            test::<u64>(
737                u64::MAX,
738                &[0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
739            )
740            .unwrap()
741        );
742    }
743
744    #[test]
745    fn i64() {
746        assert!(test::<i64>(0, &[0x00]).unwrap());
747        assert!(test::<i64>(23, &[0x17]).unwrap());
748        assert!(
749            test::<i64>(
750                i64::MAX,
751                &[0x1b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
752            )
753            .unwrap()
754        );
755        // Negative values use major type 1
756        assert!(test::<i64>(-1, &[0x20]).unwrap());
757        assert!(test::<i64>(-24, &[0x37]).unwrap());
758        assert!(test::<i64>(-25, &[0x38, 0x18]).unwrap());
759        assert!(test::<i64>(-256, &[0x38, 0xff]).unwrap());
760        assert!(
761            test::<i64>(
762                i64::MIN,
763                &[0x3b, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
764            )
765            .unwrap()
766        );
767    }
768
769    #[test]
770    fn int_full_range() {
771        // Test Int type with full CBOR integer range
772        let pos_max = Int {
773            negative: false,
774            bits: u64::MAX,
775        };
776        assert!(
777            test::<Int>(
778                pos_max,
779                &[0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
780            )
781            .unwrap()
782        );
783
784        let neg_max = Int {
785            negative: true,
786            bits: u64::MAX,
787        };
788        assert!(
789            test::<Int>(
790                neg_max,
791                &[0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
792            )
793            .unwrap()
794        );
795    }
796
797    #[test]
798    fn int_out_of_range() {
799        // -(2^64 - 1) = -18446744073709551615 can only be decoded into Int
800        use crate::Decoder;
801        let cbor = [0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff];
802
803        // Should work for Int
804        assert!(Int::decode(&mut Decoder(&cbor)).is_ok());
805
806        // Should fail for i64 due to narrowing
807        let err = i64::decode(&mut Decoder(&cbor)).unwrap_err();
808        assert_eq!(err, Error::Narrowing);
809    }
810
811    #[test]
812    fn narrowing() {
813        use crate::Decoder;
814
815        // Value too large for u32
816        let cbor = [0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00];
817        let err = u32::decode(&mut Decoder(&cbor)).unwrap_err();
818        assert_eq!(err, Error::Narrowing);
819
820        // Value too large for u16
821        let cbor = [0x19, 0xff, 0xff];
822        assert!(u16::decode(&mut Decoder(&cbor)).is_ok());
823
824        let cbor = [0x1a, 0x00, 0x01, 0x00, 0x00];
825        let err = u16::decode(&mut Decoder(&cbor)).unwrap_err();
826        assert_eq!(err, Error::Narrowing);
827
828        // Value too large for i32
829        let cbor = [0x1b, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00];
830        let err = i32::decode(&mut Decoder(&cbor)).unwrap_err();
831        assert_eq!(err, Error::Narrowing);
832
833        // Negative value too small for i32
834        let cbor = [0x3b, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00];
835        let err = i32::decode(&mut Decoder(&cbor)).unwrap_err();
836        assert_eq!(err, Error::Narrowing);
837    }
838
839    #[test]
840    fn u8() {
841        assert!(test(U8(0), &[0x00]).unwrap());
842        assert!(test(U8(42), &[0x18, 0x2a]).unwrap());
843        assert!(test(U8(255), &[0x18, 0xff]).unwrap());
844
845        let cbor = [0x19, 0x01, 0x00]; // 256
846        let err = U8::decode(&mut crate::Decoder(&cbor)).unwrap_err();
847        assert_eq!(err, Error::Narrowing);
848    }
849
850    #[test]
851    fn f32() {
852        // Values that can be represented exactly in f16 should encode in 3 bytes
853        assert!(test::<f32>(0.0, &[0xf9, 0x00, 0x00]).unwrap());
854        assert!(test::<f32>(1.0, &[0xf9, 0x3c, 0x00]).unwrap());
855        assert!(test::<f32>(-2.0, &[0xf9, 0xc0, 0x00]).unwrap());
856
857        // Values requiring f32 precision should encode in 5 bytes
858        let val = 1.1f32;
859        let cbor = [0xfa, 0x3f, 0x8c, 0xcc, 0xcd];
860        assert!(test::<f32>(val, &cbor).unwrap());
861    }
862
863    #[test]
864    fn f64() {
865        use crate::Decoder;
866        // f64 can decode from all float formats
867        let cbor_f16 = [0xf9, 0x3c, 0x00];
868        assert_eq!(f64::decode(&mut Decoder(&cbor_f16)).unwrap(), 1.0);
869
870        let cbor_f32 = [0xfa, 0x3f, 0x80, 0x00, 0x00];
871        assert_eq!(f64::decode(&mut Decoder(&cbor_f32)).unwrap(), 1.0);
872
873        let cbor_f64 = [0xfb, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
874        assert_eq!(f64::decode(&mut Decoder(&cbor_f64)).unwrap(), 1.0);
875
876        // f64 values that can be represented exactly in f16 should encode in 3 bytes
877        assert!(test::<f64>(1.0, &[0xf9, 0x3c, 0x00]).unwrap());
878        assert!(test::<f64>(-2.0, &[0xf9, 0xc0, 0x00]).unwrap());
879
880        // Values requiring f64 precision should encode in 9 bytes
881        let val = core::f64::consts::PI;
882        let cbor = [0xfb, 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18];
883        assert!(test::<f64>(val, &cbor).unwrap());
884        let err = f32::decode(&mut Decoder(&cbor)).unwrap_err();
885        assert_eq!(err, Error::Narrowing);
886
887        // f64 values that fit in f32 but not f16 should encode in 5 bytes
888        // Using a value that is exactly representable in f32
889        let val = 3.00006103515625f64; // Exactly representable in f32
890        let cbor = [0xfa, 0x40, 0x40, 0x01, 0x00];
891        assert!(test::<f64>(val, &cbor).unwrap());
892    }
893
894    #[test]
895    fn special_floats() {
896        // Test special float values
897        assert!(test::<f32>(f32::INFINITY, &[0xf9, 0x7c, 0x00]).unwrap());
898        assert!(test::<f32>(f32::NEG_INFINITY, &[0xf9, 0xfc, 0x00]).unwrap());
899
900        assert!(test::<f64>(f64::INFINITY, &[0xf9, 0x7c, 0x00]).unwrap());
901        assert!(test::<f64>(f64::NEG_INFINITY, &[0xf9, 0xfc, 0x00]).unwrap());
902
903        // NaN encoding (specific NaN bit pattern may vary)
904        use crate::{Decoder, Encoder};
905        let mut buf = Vec::new();
906        f32::NAN.encode(&mut Encoder(&mut buf)).unwrap();
907        assert!(f32::decode(&mut Decoder(&buf)).unwrap().is_nan());
908
909        buf.clear();
910        f64::NAN.encode(&mut Encoder(&mut buf)).unwrap();
911        assert!(f64::decode(&mut Decoder(&buf)).unwrap().is_nan());
912    }
913
914    #[test]
915    fn int() {
916        // Test Int conversions
917        assert_eq!(
918            Int::from(42u64),
919            Int {
920                negative: false,
921                bits: 42
922            }
923        );
924        assert_eq!(
925            Int::from(-1i64),
926            Int {
927                negative: true,
928                bits: 0
929            }
930        );
931        assert_eq!(
932            Int::from(-100i64),
933            Int {
934                negative: true,
935                bits: 99
936            }
937        );
938
939        assert_eq!(
940            i128::from(Int {
941                negative: false,
942                bits: 42
943            }),
944            42
945        );
946        assert_eq!(
947            i128::from(Int {
948                negative: true,
949                bits: 0
950            }),
951            -1
952        );
953        assert_eq!(
954            i128::from(Int {
955                negative: true,
956                bits: 99
957            }),
958            -100
959        );
960    }
961}