1use crate::{Value, tag};
2macro_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
37macro_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
86macro_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);