substreams_database_change/numeric/
impls.rs1use crate::numeric::{NumericAddable, NumericComparable, ToBigDecimal};
2use std::cmp::Ordering;
3use std::str::FromStr;
4use substreams::scalar::{BigDecimal, BigInt};
5
6macro_rules! impl_numeric_for_integer {
8 ($($t:ty),*) => {
9 $(
10 impl ToBigDecimal for $t {
11 fn to_big_decimal(&self) -> BigDecimal {
12 BigDecimal::from(*self)
13 }
14 }
15
16 impl NumericAddable for $t {
17 fn add_assign_to(&self, target: &mut BigDecimal) {
18 *target += BigDecimal::from(*self);
19 }
20
21 fn sub_assign_from(&self, target: &mut BigDecimal) {
22 *target -= BigDecimal::from(*self);
23 }
24 }
25 )*
26 };
27}
28
29macro_rules! impl_numeric_for_integer_via_cast {
31 ($($t:ty => $cast:ty),*) => {
32 $(
33 impl ToBigDecimal for $t {
34 fn to_big_decimal(&self) -> BigDecimal {
35 BigDecimal::from(*self as $cast)
36 }
37 }
38
39 impl NumericAddable for $t {
40 fn add_assign_to(&self, target: &mut BigDecimal) {
41 *target += BigDecimal::from(*self as $cast);
42 }
43
44 fn sub_assign_from(&self, target: &mut BigDecimal) {
45 *target -= BigDecimal::from(*self as $cast);
46 }
47 }
48 )*
49 };
50}
51
52impl_numeric_for_integer!(i32, i64, u32, u64);
54
55impl_numeric_for_integer_via_cast!(
57 i8 => i64,
58 i16 => i64,
59 u8 => u64,
60 u16 => u64,
61 isize => i64,
62 usize => u64
63);
64
65impl ToBigDecimal for i128 {
67 fn to_big_decimal(&self) -> BigDecimal {
68 BigDecimal::from_str(&self.to_string())
69 .expect("i128 should always convert to BigDecimal")
70 }
71}
72
73impl NumericAddable for i128 {
74 fn add_assign_to(&self, target: &mut BigDecimal) {
75 *target += self.to_big_decimal();
76 }
77
78 fn sub_assign_from(&self, target: &mut BigDecimal) {
79 *target -= self.to_big_decimal();
80 }
81}
82
83impl ToBigDecimal for u128 {
84 fn to_big_decimal(&self) -> BigDecimal {
85 BigDecimal::from_str(&self.to_string())
86 .expect("u128 should always convert to BigDecimal")
87 }
88}
89
90impl NumericAddable for u128 {
91 fn add_assign_to(&self, target: &mut BigDecimal) {
92 *target += self.to_big_decimal();
93 }
94
95 fn sub_assign_from(&self, target: &mut BigDecimal) {
96 *target -= self.to_big_decimal();
97 }
98}
99
100impl ToBigDecimal for BigDecimal {
101 fn to_big_decimal(&self) -> BigDecimal {
102 self.clone()
103 }
104}
105
106impl NumericAddable for BigDecimal {
107 fn add_assign_to(&self, target: &mut BigDecimal) {
108 *target += self;
109 }
110
111 fn sub_assign_from(&self, target: &mut BigDecimal) {
112 *target -= self;
113 }
114}
115
116impl ToBigDecimal for &BigDecimal {
117 fn to_big_decimal(&self) -> BigDecimal {
118 (*self).clone()
119 }
120}
121
122impl NumericAddable for &BigDecimal {
123 fn add_assign_to(&self, target: &mut BigDecimal) {
124 *target += *self;
125 }
126
127 fn sub_assign_from(&self, target: &mut BigDecimal) {
128 *target -= *self;
129 }
130}
131
132impl ToBigDecimal for BigInt {
133 fn to_big_decimal(&self) -> BigDecimal {
134 BigDecimal::from(self.clone())
135 }
136}
137
138impl NumericAddable for BigInt {
139 fn add_assign_to(&self, target: &mut BigDecimal) {
140 *target += BigDecimal::from(self.clone());
141 }
142
143 fn sub_assign_from(&self, target: &mut BigDecimal) {
144 *target -= BigDecimal::from(self.clone());
145 }
146}
147
148impl ToBigDecimal for &BigInt {
149 fn to_big_decimal(&self) -> BigDecimal {
150 BigDecimal::from((*self).clone())
151 }
152}
153
154impl NumericAddable for &BigInt {
155 fn add_assign_to(&self, target: &mut BigDecimal) {
156 *target += BigDecimal::from((*self).clone());
157 }
158
159 fn sub_assign_from(&self, target: &mut BigDecimal) {
160 *target -= BigDecimal::from((*self).clone());
161 }
162}
163
164macro_rules! impl_numeric_for_string {
166 ($($t:ty),*) => {
167 $(
168 impl ToBigDecimal for $t {
169 fn to_big_decimal(&self) -> BigDecimal {
170 BigDecimal::from_str(self).unwrap_or_else(|_| {
171 panic!(
172 "add/sub() requires a valid numeric value, got: {}",
173 self
174 )
175 })
176 }
177 }
178
179 impl NumericAddable for $t {
180 fn add_assign_to(&self, target: &mut BigDecimal) {
181 let value = self.to_big_decimal();
182 *target += value;
183 }
184
185 fn sub_assign_from(&self, target: &mut BigDecimal) {
186 let value = self.to_big_decimal();
187 *target -= value;
188 }
189 }
190 )*
191 };
192}
193
194impl_numeric_for_string!(String, &str);
196
197macro_rules! impl_numeric_comparable_for_integer {
203 ($($t:ty),*) => {
204 $(
205 impl NumericComparable for $t {
206 fn cmp_to_big_decimal(&self, other: &BigDecimal) -> Ordering {
207 self.partial_cmp(other)
210 .expect(concat!("BigDecimal comparison should always succeed for ", stringify!($t)))
211 }
212 }
213 )*
214 };
215}
216
217impl_numeric_comparable_for_integer!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128);
219
220impl NumericComparable for isize {
222 fn cmp_to_big_decimal(&self, other: &BigDecimal) -> Ordering {
223 (*self as i64).partial_cmp(other)
224 .expect("BigDecimal comparison should always succeed for isize")
225 }
226}
227
228impl NumericComparable for usize {
229 fn cmp_to_big_decimal(&self, other: &BigDecimal) -> Ordering {
230 (*self as u64).partial_cmp(other)
231 .expect("BigDecimal comparison should always succeed for usize")
232 }
233}
234
235impl NumericComparable for BigDecimal {
237 fn cmp_to_big_decimal(&self, other: &BigDecimal) -> Ordering {
238 self.cmp(other)
239 }
240}
241
242impl NumericComparable for &BigDecimal {
243 fn cmp_to_big_decimal(&self, other: &BigDecimal) -> Ordering {
244 (*self).cmp(other)
245 }
246}
247
248impl NumericComparable for BigInt {
250 fn cmp_to_big_decimal(&self, other: &BigDecimal) -> Ordering {
251 let self_bd = BigDecimal::from(self.clone());
252 self_bd.cmp(other)
253 }
254}
255
256impl NumericComparable for &BigInt {
257 fn cmp_to_big_decimal(&self, other: &BigDecimal) -> Ordering {
258 let self_bd = BigDecimal::from((*self).clone());
259 self_bd.cmp(other)
260 }
261}