substreams_ethereum_core/
scalar.rs

1use crate::pb::eth::v2 as pb;
2use substreams::scalar::{BigDecimal, BigInt};
3
4impl Into<BigInt> for pb::BigInt {
5    fn into(self) -> BigInt {
6        Into::<BigInt>::into(&self)
7    }
8}
9
10impl Into<BigInt> for &pb::BigInt {
11    fn into(self) -> BigInt {
12        BigInt::from_unsigned_bytes_be(self.bytes.as_ref())
13    }
14}
15
16impl Into<BigDecimal> for pb::BigInt {
17    fn into(self) -> BigDecimal {
18        Into::<BigDecimal>::into(&self)
19    }
20}
21
22impl Into<BigDecimal> for &pb::BigInt {
23    fn into(self) -> BigDecimal {
24        let v = BigInt::from_unsigned_bytes_be(self.bytes.as_ref());
25        BigDecimal::new(v, 0)
26    }
27}
28
29pub fn to_option_decimal(v: Option<pb::BigInt>) -> Option<BigDecimal> {
30    match v {
31        Some(v) => {
32            let out: BigDecimal = v.into();
33            Some(out)
34        }
35        None => None,
36    }
37}
38
39pub fn to_option_bigint(v: Option<pb::BigInt>) -> Option<BigInt> {
40    match v {
41        Some(v) => Some(v.into()),
42        None => None,
43    }
44}
45
46pub fn to_option_decimal_with_decimal(v: Option<pb::BigInt>, decimal: u32) -> Option<BigDecimal> {
47    match v {
48        Some(v) => Some(v.with_decimal(decimal)),
49        None => None,
50    }
51}
52
53impl pb::BigInt {
54    pub fn with_decimal(self, decimal: u32) -> BigDecimal {
55        let num: BigDecimal = self.into();
56        let dem = BigInt::from(10 as u32).pow(decimal);
57        return num / BigDecimal::from(dem);
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use crate::pb::eth::v2 as pb;
64    use crate::scalar::{to_option_bigint, to_option_decimal, to_option_decimal_with_decimal};
65
66    #[test]
67    fn zero_into_bigint() {
68        let v: substreams::scalar::BigInt = new_pb_bigint(0).into();
69        assert_eq!(v.to_u64(), 0);
70    }
71
72    #[test]
73    fn number_into_bigint() {
74        let v: substreams::scalar::BigInt = new_pb_bigint(253).into();
75        assert_eq!(v.to_u64(), 253);
76
77        let pb = new_pb_bigint(254);
78        let pb_ref = &pb;
79        let v: substreams::scalar::BigInt = pb_ref.into();
80        assert_eq!(v.to_u64(), 254);
81    }
82
83    #[test]
84    fn zero_into_bigdecmal() {
85        let v: substreams::scalar::BigDecimal = new_pb_bigint(0).into();
86        assert_eq!(v.to_string(), "0");
87    }
88
89    #[test]
90    fn number_into_bigdecmal() {
91        let v: substreams::scalar::BigDecimal = new_pb_bigint(253).into();
92        assert_eq!(v.to_string(), "253");
93
94        let pb = new_pb_bigint(254);
95        let pb_ref = &pb;
96        let v: substreams::scalar::BigInt = pb_ref.into();
97        assert_eq!(v.to_string(), "254");
98    }
99
100    #[test]
101    fn some_option_pb_to_decimal() {
102        let v = Some(new_pb_bigint(253));
103        assert_eq!(
104            to_option_decimal(v),
105            Some(substreams::scalar::BigDecimal::from(253 as u32))
106        );
107    }
108
109    #[test]
110    fn none_option_pb_to_decimal() {
111        let v: Option<pb::BigInt> = None;
112        assert_eq!(to_option_decimal(v), None);
113    }
114
115    #[test]
116    fn some_option_pb_to_bigint() {
117        let v = Some(new_pb_bigint(253));
118        assert_eq!(
119            to_option_bigint(v),
120            Some(substreams::scalar::BigInt::from(253 as u32))
121        );
122    }
123
124    #[test]
125    fn none_option_pb_to_bigint() {
126        let v: Option<pb::BigInt> = None;
127        assert_eq!(to_option_bigint(v), None);
128    }
129
130    #[test]
131    fn with_decimal() {
132        let v = new_pb_bigint_bytes(vec![114, 10, 199, 169, 74, 64, 0].as_ref());
133        assert_eq!(v.with_decimal(18).to_string(), "0.0321");
134    }
135
136    #[test]
137    fn some_option_pb_to_bigdecimal_with_decimal() {
138        let v = Some(new_pb_bigint_bytes(
139            vec![114, 10, 199, 169, 74, 64, 0].as_ref(),
140        ));
141        let out = substreams::scalar::BigDecimal::try_from("0.0321".to_owned()).unwrap();
142        assert_eq!(to_option_decimal_with_decimal(v, 18), Some(out));
143    }
144
145    #[test]
146    fn none_option_pb_to_bigdecimal_with_decimal() {
147        let v: Option<pb::BigInt> = None;
148        assert_eq!(to_option_decimal_with_decimal(v, 18), None);
149    }
150
151    #[test]
152    fn some_option_pb_to_bigdecimal() {
153        let v = Some(new_pb_bigint(253));
154        assert_eq!(
155            to_option_decimal(v),
156            Some(substreams::scalar::BigDecimal::from(253 as u32))
157        );
158    }
159
160    #[test]
161    fn none_option_pb_to_bigdecimal() {
162        let v: Option<pb::BigInt> = None;
163        assert_eq!(to_option_decimal(v), None);
164    }
165
166    pub fn new_pb_bigint(value: u32) -> pb::BigInt {
167        let v = num_bigint::BigInt::new(num_bigint::Sign::Plus, vec![value]);
168        let (_, bytes) = v.to_bytes_be();
169        pb::BigInt { bytes }
170    }
171
172    pub fn new_pb_bigint_bytes(bytes: &[u8]) -> pb::BigInt {
173        let v = num_bigint::BigInt::from_bytes_be(num_bigint::Sign::Plus, bytes);
174        let (_, bytes) = v.to_bytes_be();
175        pb::BigInt { bytes }
176    }
177}