chaincodec_evm/
normalizer.rs1use alloy_core::dyn_abi::DynSolValue;
7use alloy_primitives::U256;
8use chaincodec_core::types::NormalizedValue;
9
10pub fn normalize(val: DynSolValue) -> NormalizedValue {
12 match val {
13 DynSolValue::Bool(b) => NormalizedValue::Bool(b),
14
15 DynSolValue::Int(i, bits) => {
16 if bits <= 128 {
18 match i128::try_from(i) {
20 Ok(v) => NormalizedValue::Int(v),
21 Err(_) => NormalizedValue::BigInt(i.to_string()),
22 }
23 } else {
24 NormalizedValue::BigInt(i.to_string())
25 }
26 }
27
28 DynSolValue::Uint(u, bits) => {
29 if bits <= 128 {
30 match u128::try_from(u) {
31 Ok(v) => NormalizedValue::Uint(v),
32 Err(_) => NormalizedValue::BigUint(u.to_string()),
33 }
34 } else {
35 NormalizedValue::BigUint(u.to_string())
36 }
37 }
38
39 DynSolValue::FixedBytes(bytes, _size) => {
40 NormalizedValue::Bytes(bytes.to_vec())
41 }
42
43 DynSolValue::Bytes(b) => NormalizedValue::Bytes(b),
44
45 DynSolValue::String(s) => NormalizedValue::Str(s),
46
47 DynSolValue::Address(a) => {
48 NormalizedValue::Address(format!("{a:#x}"))
50 }
51
52 DynSolValue::Array(vals) | DynSolValue::FixedArray(vals) => {
53 NormalizedValue::Array(vals.into_iter().map(normalize).collect())
54 }
55
56 DynSolValue::Tuple(fields) => {
57 let named: Vec<(String, NormalizedValue)> = fields
59 .into_iter()
60 .enumerate()
61 .map(|(i, v)| (i.to_string(), normalize(v)))
62 .collect();
63 NormalizedValue::Tuple(named)
64 }
65
66 DynSolValue::Function(f) => NormalizedValue::Bytes(f.to_vec()),
68 }
69}
70
71pub fn normalize_u256_hex(hex_str: &str) -> NormalizedValue {
73 let hex = hex_str.strip_prefix("0x").unwrap_or(hex_str);
74 match U256::from_str_radix(hex, 16) {
75 Ok(u) => match u128::try_from(u) {
76 Ok(v) => NormalizedValue::Uint(v),
77 Err(_) => NormalizedValue::BigUint(u.to_string()),
78 },
79 Err(_) => NormalizedValue::Null,
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use alloy_primitives::{Address, U256};
87
88 #[test]
89 fn normalize_bool() {
90 let v = normalize(DynSolValue::Bool(true));
91 assert_eq!(v, NormalizedValue::Bool(true));
92 }
93
94 #[test]
95 fn normalize_uint256_small() {
96 let u = DynSolValue::Uint(U256::from(42u64), 256);
97 let v = normalize(u);
98 assert_eq!(v, NormalizedValue::Uint(42));
99 }
100
101 #[test]
102 fn normalize_address() {
103 let addr: Address = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
104 .parse()
105 .unwrap();
106 let v = normalize(DynSolValue::Address(addr));
107 assert!(matches!(v, NormalizedValue::Address(_)));
108 if let NormalizedValue::Address(s) = v {
109 assert!(s.starts_with("0x"));
110 }
111 }
112}