icydb_schema/
numeric_value.rs1use crate::{Decimal, Duration, Float32, Float64, Timestamp};
7
8pub trait NumericValue: Sized {
13 fn try_to_decimal(&self) -> Option<Decimal>;
15
16 fn try_from_decimal(value: Decimal) -> Option<Self>;
18}
19
20macro_rules! impl_numeric_value_signed {
21 ($($ty:ty),* $(,)?) => {
22 $(
23 impl NumericValue for $ty {
24 fn try_to_decimal(&self) -> Option<Decimal> {
25 Decimal::from_i128(i128::from(*self))
26 }
27
28 fn try_from_decimal(value: Decimal) -> Option<Self> {
29 value.to_i128().and_then(|inner| Self::try_from(inner).ok())
30 }
31 }
32 )*
33 };
34}
35
36macro_rules! impl_numeric_value_unsigned {
37 ($($ty:ty),* $(,)?) => {
38 $(
39 impl NumericValue for $ty {
40 fn try_to_decimal(&self) -> Option<Decimal> {
41 Decimal::from_u128(u128::from(*self))
42 }
43
44 fn try_from_decimal(value: Decimal) -> Option<Self> {
45 value.to_u128().and_then(|inner| Self::try_from(inner).ok())
46 }
47 }
48 )*
49 };
50}
51
52impl_numeric_value_signed!(i8, i16, i32, i64, i128);
53impl_numeric_value_unsigned!(u8, u16, u32, u64, u128);
54
55impl NumericValue for isize {
56 fn try_to_decimal(&self) -> Option<Decimal> {
57 Decimal::from_i128(i128::try_from(*self).ok()?)
58 }
59
60 fn try_from_decimal(value: Decimal) -> Option<Self> {
61 value.to_i128().and_then(|inner| Self::try_from(inner).ok())
62 }
63}
64
65impl NumericValue for usize {
66 fn try_to_decimal(&self) -> Option<Decimal> {
67 Decimal::from_u128(u128::try_from(*self).ok()?)
68 }
69
70 fn try_from_decimal(value: Decimal) -> Option<Self> {
71 value.to_u128().and_then(|inner| Self::try_from(inner).ok())
72 }
73}
74
75impl NumericValue for f32 {
76 fn try_to_decimal(&self) -> Option<Decimal> {
77 Decimal::from_f32_lossy(*self)
78 }
79
80 fn try_from_decimal(value: Decimal) -> Option<Self> {
81 value.to_f32()
82 }
83}
84
85impl NumericValue for f64 {
86 fn try_to_decimal(&self) -> Option<Decimal> {
87 Decimal::from_f64_lossy(*self)
88 }
89
90 fn try_from_decimal(value: Decimal) -> Option<Self> {
91 value.to_f64()
92 }
93}
94
95impl NumericValue for Duration {
96 fn try_to_decimal(&self) -> Option<Decimal> {
97 Decimal::from_u64(self.as_millis())
98 }
99
100 fn try_from_decimal(value: Decimal) -> Option<Self> {
101 value.to_u64().map(Self::from_millis)
102 }
103}
104
105impl NumericValue for Float32 {
106 fn try_to_decimal(&self) -> Option<Decimal> {
107 Decimal::from_f32_lossy(self.get())
108 }
109
110 fn try_from_decimal(value: Decimal) -> Option<Self> {
111 value.to_f32().and_then(Self::try_new)
112 }
113}
114
115impl NumericValue for Float64 {
116 fn try_to_decimal(&self) -> Option<Decimal> {
117 Decimal::from_f64_lossy(self.get())
118 }
119
120 fn try_from_decimal(value: Decimal) -> Option<Self> {
121 value.to_f64().and_then(Self::try_new)
122 }
123}
124
125impl NumericValue for Timestamp {
126 fn try_to_decimal(&self) -> Option<Decimal> {
127 Decimal::from_i64(self.as_millis())
128 }
129
130 fn try_from_decimal(value: Decimal) -> Option<Self> {
131 value.to_i64().map(Self::from_millis)
132 }
133}