Skip to main content

cbor_core/value/
int.rs

1use crate::{Value, tag};
2// --------- From unsigned ints ---------
3
4macro_rules! try_from_uint {
5    ($type:ty) => {
6        impl From<$type> for Value {
7            fn from(value: $type) -> Self {
8                Self::Unsigned(value.into())
9            }
10        }
11    };
12}
13
14try_from_uint!(u8);
15try_from_uint!(u16);
16try_from_uint!(u32);
17try_from_uint!(u64);
18
19impl From<u128> for Value {
20    fn from(value: u128) -> Self {
21        if value <= u64::MAX as u128 {
22            Self::Unsigned(value as u64)
23        } else {
24            let bytes: Vec<u8> = value.to_be_bytes().into_iter().skip_while(|&byte| byte == 0).collect();
25            debug_assert!(bytes.len() > 8);
26            Self::tag(tag::POS_BIG_INT, bytes)
27        }
28    }
29}
30
31impl From<usize> for Value {
32    fn from(value: usize) -> Self {
33        Self::Unsigned(value.try_into().unwrap())
34    }
35}
36
37// --------- From signed ints ---------
38
39macro_rules! try_from_sint {
40    ($type:ty) => {
41        impl From<$type> for Value {
42            fn from(value: $type) -> Self {
43                if value >= 0 {
44                    Self::Unsigned(value as u64)
45                } else {
46                    Self::Negative((!value) as u64)
47                }
48            }
49        }
50    };
51}
52
53try_from_sint!(i8);
54try_from_sint!(i16);
55try_from_sint!(i32);
56try_from_sint!(i64);
57
58impl From<i128> for Value {
59    fn from(value: i128) -> Self {
60        if value >= 0 {
61            Self::from(value as u128)
62        } else {
63            let complement = (!value) as u128;
64
65            if complement <= u64::MAX as u128 {
66                Self::Negative(complement as u64)
67            } else {
68                let bytes: Vec<u8> = complement
69                    .to_be_bytes()
70                    .into_iter()
71                    .skip_while(|&byte| byte == 0)
72                    .collect();
73                debug_assert!(bytes.len() > 8);
74                Self::tag(tag::NEG_BIG_INT, bytes)
75            }
76        }
77    }
78}
79
80impl From<isize> for Value {
81    fn from(value: isize) -> Self {
82        Self::from(i64::try_from(value).unwrap())
83    }
84}
85
86// --------- TryFrom Value ---------
87
88macro_rules! try_from_value {
89    ($type:ty, $to_x:ident) => {
90        impl TryFrom<Value> for $type {
91            type Error = crate::Error;
92            fn try_from(value: Value) -> crate::Result<Self> {
93                value.$to_x()
94            }
95        }
96
97        impl TryFrom<&Value> for $type {
98            type Error = crate::Error;
99            fn try_from(value: &Value) -> crate::Result<Self> {
100                value.$to_x()
101            }
102        }
103    };
104}
105
106try_from_value!(u8, to_u8);
107try_from_value!(u16, to_u16);
108try_from_value!(u32, to_u32);
109try_from_value!(u64, to_u64);
110try_from_value!(u128, to_u128);
111try_from_value!(usize, to_usize);
112
113try_from_value!(i8, to_i8);
114try_from_value!(i16, to_i16);
115try_from_value!(i32, to_i32);
116try_from_value!(i64, to_i64);
117try_from_value!(i128, to_i128);
118try_from_value!(isize, to_isize);