1use alloy_primitives::U256;
16use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
17use serde_json::Value;
18
19pub fn serialize<S>(value: &Option<U256>, serializer: S) -> Result<S::Ok, S::Error>
23where
24 S: Serializer,
25{
26 if serializer.is_human_readable() {
27 match value {
28 Some(value) => {
29 match value.try_into() {
31 Ok(value) => serializer.serialize_u128(value),
32 Err(_) => value.serialize(serializer),
33 }
34 }
35 None => serializer.serialize_none(),
36 }
37 } else {
38 value.serialize(serializer)
39 }
40}
41
42pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
44where
45 D: Deserializer<'de>,
46{
47 if deserializer.is_human_readable() {
48 Option::<Value>::deserialize(deserializer)?
49 .map_or_else(|| Ok(None), |value| ttd_from_value::<D>(value).map(Some))
50 } else {
51 Option::<U256>::deserialize(deserializer)
52 }
53}
54
55pub fn deserialize_json_ttd_opt<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
58where
59 D: Deserializer<'de>,
60{
61 deserialize(deserializer)
62}
63
64fn ttd_from_value<'de, D>(val: Value) -> Result<U256, D::Error>
66where
67 D: Deserializer<'de>,
68{
69 let val = match val {
70 Value::Number(num) => num,
71 Value::String(raw) => return raw.parse().map_err(<D::Error as de::Error>::custom),
72 _ => return Err(de::Error::custom("TTD must be a number or string")),
73 };
74
75 let num = if let Some(val) = val.as_u64() {
76 U256::from(val)
77 } else if let Some(value) = val.as_f64() {
78 if value == 5.875e22 {
96 U256::from(58750000000000000000000u128)
97 } else {
98 return Err(de::Error::custom(
101 "Deserializing a large non-mainnet TTD is not supported",
102 ));
103 }
104 } else {
105 return Err(de::Error::custom(
107 "Negative TTD values are invalid and will not be deserialized",
108 ));
109 };
110
111 Ok(num)
112}
113#[cfg(test)]
114mod tests {
115 #[cfg(not(feature = "std"))]
116 use alloc::{vec, vec::Vec};
117 use alloy_primitives::U256;
118 use serde::{Deserialize, Serialize};
119 use serde_json::json;
120
121 #[test]
122 fn jsonu256_deserialize() {
123 let deserialized: Vec<U256> =
124 serde_json::from_str(r#"["","0", "0x","10",10,"0x10"]"#).unwrap();
125 assert_eq!(
126 deserialized,
127 vec![
128 U256::ZERO,
129 U256::ZERO,
130 U256::ZERO,
131 U256::from(10),
132 U256::from(10),
133 U256::from(16),
134 ]
135 );
136 }
137
138 #[test]
139 fn jsonu256_serialize() {
140 let data = U256::from(16);
141 let serialized = serde_json::to_string(&data).unwrap();
142
143 assert_eq!(serialized, r#""0x10""#);
144 }
145
146 #[test]
147 fn deserialize_ttd() {
148 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
149 struct Ttd(#[serde(with = "super")] Option<U256>);
150
151 let deserialized: Vec<Ttd> = serde_json::from_str(
152 r#"["",0,"0","0x0",18446744073709551615,58750000000000000000000,"58750000000000000000000","0xC70D808A128D7380000"]"#,
153 )
154 .unwrap();
155 assert_eq!(
156 deserialized,
157 vec![
158 Ttd(Some(U256::ZERO)),
159 Ttd(Some(U256::ZERO)),
160 Ttd(Some(U256::ZERO)),
161 Ttd(Some(U256::ZERO)),
162 Ttd(Some(U256::from(18446744073709551615u64))),
163 Ttd(Some(U256::from(58750000000000000000000u128))),
164 Ttd(Some(U256::from(58750000000000000000000u128))),
165 Ttd(Some(U256::from(58750000000000000000000u128))),
166 ]
167 );
168 }
169
170 #[test]
171 fn serialize_ttd() {
172 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
173 struct Ttd(#[serde(with = "super")] Option<U256>);
174
175 let tests = vec![
176 Ttd(Some(U256::ZERO)),
177 Ttd(Some(U256::from(17000000000000000u64))),
178 Ttd(Some(U256::from(58750000000000000000000u128))),
179 Ttd(Some(U256::from(u128::MAX))),
180 ];
181
182 for test in tests {
183 let str = serde_json::to_string(&test).unwrap();
184 let num = str.parse::<u128>().unwrap();
186 assert!(matches!(test, Ttd(Some(ttd)) if ttd == U256::from(num)));
187 }
188 }
189
190 #[test]
191 fn deserialize_ttd_untagged_enum() {
192 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
193 #[serde(untagged)]
194 enum Ttd {
195 Ttd(#[serde(with = "super")] Option<U256>),
196 }
197 let test = Ttd::Ttd(Some(U256::from(58750000000000000000000u128)));
198 let str = serde_json::to_string(&test).unwrap();
199 assert_eq!(str, r#"58750000000000000000000"#);
201
202 let deserialized: Ttd = serde_json::from_str(&str).unwrap();
203 assert_eq!(deserialized, test);
204 }
205
206 #[test]
207 fn deserialize_ttd_none() {
208 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
209 struct Ttd(#[serde(with = "super")] Option<U256>);
210
211 let deserialized: Ttd = serde_json::from_value(json!(null)).unwrap();
213 assert_eq!(deserialized, Ttd(None));
214 }
215
216 #[test]
217 fn deserialize_ttd_invalid_string() {
218 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
219 struct Ttd(#[serde(with = "super")] Option<U256>);
220
221 let result: Result<Ttd, _> = serde_json::from_value(json!("invalid_string"));
223 assert!(result.is_err());
224 }
225
226 #[test]
227 fn deserialize_ttd_large_non_mainnet() {
228 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
229 struct Ttd(#[serde(with = "super")] Option<U256>);
230
231 let result: Result<Ttd, _> = serde_json::from_value(json!(6.0e22));
233 assert!(result.is_err());
234 }
235
236 #[test]
237 fn deserialize_ttd_negative_number() {
238 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
239 struct Ttd(#[serde(with = "super")] Option<U256>);
240
241 let result: Result<Ttd, _> = serde_json::from_value(json!(-1));
243 assert!(result.is_err());
244 }
245
246 #[test]
247 fn deserialize_ttd_as_string() {
248 #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
249 struct Ttd(#[serde(with = "super")] Option<U256>);
250
251 let deserialized: Ttd = serde_json::from_value(json!("0x12345")).unwrap();
253 assert_eq!(deserialized, Ttd(Some(U256::from(0x12345))));
254 }
255}