foundry_common/
serde_helpers.rs
1use alloy_primitives::U256;
4use serde::{de, Deserialize, Deserializer};
5use std::str::FromStr;
6
7#[derive(Copy, Clone, Deserialize)]
9#[serde(untagged)]
10pub enum Numeric {
11 U256(U256),
13 Num(u64),
15}
16
17impl From<Numeric> for U256 {
18 fn from(n: Numeric) -> Self {
19 match n {
20 Numeric::U256(n) => n,
21 Numeric::Num(n) => Self::from(n),
22 }
23 }
24}
25
26impl FromStr for Numeric {
27 type Err = String;
28
29 fn from_str(s: &str) -> Result<Self, Self::Err> {
30 if let Ok(val) = s.parse::<u128>() {
31 Ok(Self::U256(U256::from(val)))
32 } else if s.starts_with("0x") {
33 U256::from_str_radix(s, 16).map(Numeric::U256).map_err(|err| err.to_string())
34 } else {
35 U256::from_str(s).map(Numeric::U256).map_err(|err| err.to_string())
36 }
37 }
38}
39
40pub fn from_int_or_hex_opt<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
43where
44 D: Deserializer<'de>,
45{
46 match Option::<NumberOrHexU256>::deserialize(deserializer)? {
47 Some(val) => val.try_into_u256().map(Some),
48 None => Ok(None),
49 }
50}
51
52#[derive(Debug, Deserialize)]
54#[serde(untagged)]
55pub enum NumberOrHexU256 {
56 Int(serde_json::Number),
58 Hex(U256),
60}
61
62impl NumberOrHexU256 {
63 pub fn try_into_u256<E: de::Error>(self) -> Result<U256, E> {
65 match self {
66 Self::Int(num) => U256::from_str(num.to_string().as_str()).map_err(E::custom),
67 Self::Hex(val) => Ok(val),
68 }
69 }
70}
71
72pub fn from_int_or_hex<'de, D>(deserializer: D) -> Result<U256, D::Error>
75where
76 D: Deserializer<'de>,
77{
78 NumberOrHexU256::deserialize(deserializer)?.try_into_u256()
79}
80
81#[derive(Deserialize)]
83#[serde(untagged)]
84pub enum NumericSeq {
85 Seq([Numeric; 1]),
87 U256(U256),
89 Num(u64),
91}
92
93pub fn deserialize_number<'de, D>(deserializer: D) -> Result<U256, D::Error>
95where
96 D: Deserializer<'de>,
97{
98 Numeric::deserialize(deserializer).map(Into::into)
99}
100
101pub fn deserialize_number_opt<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
103where
104 D: Deserializer<'de>,
105{
106 let num = match Option::<Numeric>::deserialize(deserializer)? {
107 Some(Numeric::U256(n)) => Some(n),
108 Some(Numeric::Num(n)) => Some(U256::from(n)),
109 _ => None,
110 };
111
112 Ok(num)
113}
114
115pub fn deserialize_number_seq<'de, D>(deserializer: D) -> Result<U256, D::Error>
117where
118 D: Deserializer<'de>,
119{
120 let num = match NumericSeq::deserialize(deserializer)? {
121 NumericSeq::Seq(seq) => seq[0].into(),
122 NumericSeq::U256(n) => n,
123 NumericSeq::Num(n) => U256::from(n),
124 };
125
126 Ok(num)
127}