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
31#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
32impl From<usize> for Value {
33 fn from(value: usize) -> Self {
34 Self::Unsigned(value as u64)
35 }
36}
37
38macro_rules! try_from_sint {
41 ($type:ty) => {
42 impl From<$type> for Value {
43 fn from(value: $type) -> Self {
44 if value >= 0 {
45 Self::Unsigned(value as u64)
46 } else {
47 Self::Negative((!value) as u64)
48 }
49 }
50 }
51 };
52}
53
54try_from_sint!(i8);
55try_from_sint!(i16);
56try_from_sint!(i32);
57try_from_sint!(i64);
58
59impl From<i128> for Value {
60 fn from(value: i128) -> Self {
61 if value >= 0 {
62 Self::from(value as u128)
63 } else {
64 let complement = (!value) as u128;
65
66 if complement <= u64::MAX as u128 {
67 Self::Negative(complement as u64)
68 } else {
69 let bytes: Vec<u8> = complement
70 .to_be_bytes()
71 .into_iter()
72 .skip_while(|&byte| byte == 0)
73 .collect();
74 debug_assert!(bytes.len() > 8);
75 Self::tag(tag::NEG_BIG_INT, bytes)
76 }
77 }
78 }
79}
80
81#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
82impl From<isize> for Value {
83 fn from(value: isize) -> Self {
84 Self::from(value as i64)
85 }
86}
87
88macro_rules! try_from_value {
91 ($type:ty, $to_x:ident) => {
92 impl TryFrom<Value> for $type {
93 type Error = crate::Error;
94 fn try_from(value: Value) -> crate::Result<Self> {
95 value.$to_x()
96 }
97 }
98
99 impl TryFrom<&Value> for $type {
100 type Error = crate::Error;
101 fn try_from(value: &Value) -> crate::Result<Self> {
102 value.$to_x()
103 }
104 }
105 };
106}
107
108try_from_value!(u8, to_u8);
109try_from_value!(u16, to_u16);
110try_from_value!(u32, to_u32);
111try_from_value!(u64, to_u64);
112try_from_value!(u128, to_u128);
113try_from_value!(usize, to_usize);
114
115try_from_value!(i8, to_i8);
116try_from_value!(i16, to_i16);
117try_from_value!(i32, to_i32);
118try_from_value!(i64, to_i64);
119try_from_value!(i128, to_i128);
120try_from_value!(isize, to_isize);