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