ciborium/value/
integer.rs

1// SPDX-License-Identifier: Apache-2.0
2
3macro_rules! implfrom {
4    ($( $(#[$($attr:meta)+])? $t:ident)+) => {
5        $(
6            $(#[$($attr)+])?
7            impl From<$t> for Integer {
8                #[inline]
9                fn from(value: $t) -> Self {
10                    Self(value as _)
11                }
12            }
13
14            impl TryFrom<Integer> for $t {
15                type Error = core::num::TryFromIntError;
16
17                #[inline]
18                fn try_from(value: Integer) -> Result<Self, Self::Error> {
19                    $t::try_from(value.0)
20                }
21            }
22        )+
23    };
24}
25
26/// An abstract integer value
27///
28/// This opaque type represents an integer value which can be encoded in CBOR
29/// without resulting to big integer encoding. Larger values may be encoded
30/// using the big integer encoding as described in the CBOR RFC. See the
31/// implementations for 128-bit integer conversions on `Value` for more
32/// details.
33#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
34pub struct Integer(i128);
35
36implfrom! {
37    u8 u16 u32 u64
38    i8 i16 i32 i64
39
40    #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
41    usize
42
43    #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
44    isize
45}
46
47impl TryFrom<i128> for Integer {
48    type Error = core::num::TryFromIntError;
49
50    #[inline]
51    fn try_from(value: i128) -> Result<Self, Self::Error> {
52        u64::try_from(match value.is_negative() {
53            false => value,
54            true => value ^ !0,
55        })?;
56
57        Ok(Integer(value))
58    }
59}
60
61impl TryFrom<u128> for Integer {
62    type Error = core::num::TryFromIntError;
63
64    #[inline]
65    fn try_from(value: u128) -> Result<Self, Self::Error> {
66        Ok(Self(u64::try_from(value)?.into()))
67    }
68}
69
70impl From<Integer> for i128 {
71    #[inline]
72    fn from(value: Integer) -> Self {
73        value.0
74    }
75}
76
77impl TryFrom<Integer> for u128 {
78    type Error = core::num::TryFromIntError;
79
80    #[inline]
81    fn try_from(value: Integer) -> Result<Self, Self::Error> {
82        u128::try_from(value.0)
83    }
84}