use alloy_primitives::U256;
use serde::Serializer;
#[allow(clippy::type_complexity, reason = "serde Serializer trait requires this signature")]
pub fn u256_to_dec_string<S: Serializer>(value: &U256, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&value.to_string())
}
#[derive(Debug, Clone, Copy)]
pub struct U256DecString(pub U256);
impl serde::Serialize for U256DecString {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&self.0.to_string())
}
}
pub fn json_with_bigint_replacer<T: serde::Serialize>(
value: &T,
) -> Result<String, serde_json::Error> {
serde_json::to_string(value)
}
pub mod u256_string {
use alloy_primitives::U256;
use serde::{Deserialize, Deserializer, Serializer};
#[allow(clippy::type_complexity, reason = "serde Serializer trait requires this signature")]
pub fn serialize<S: Serializer>(value: &U256, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&value.to_string())
}
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<U256, D::Error> {
let s = String::deserialize(deserializer)?;
s.parse::<U256>().map_err(serde::de::Error::custom)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn u256_dec_string_serialises_correctly() {
let w = U256DecString(U256::from(42u64));
let json = serde_json::to_string(&w).unwrap();
assert_eq!(json, "\"42\"");
}
#[test]
fn u256_dec_string_large_value() {
let w = U256DecString(U256::MAX);
let json = serde_json::to_string(&w).unwrap();
assert!(json.starts_with('"'));
assert!(json.ends_with('"'));
assert!(json.len() > 10);
}
#[test]
fn u256_string_module_roundtrip() {
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Wrapper {
#[serde(with = "u256_string")]
value: U256,
}
let w = Wrapper { value: U256::from(999u64) };
let json = serde_json::to_string(&w).unwrap();
assert!(json.contains("\"999\""));
let back: Wrapper = serde_json::from_str(&json).unwrap();
assert_eq!(back, w);
}
#[test]
fn json_with_bigint_replacer_simple_struct() {
use serde::Serialize;
#[derive(Serialize)]
struct Simple {
name: String,
count: u32,
}
let s = Simple { name: "test".into(), count: 42 };
let json = json_with_bigint_replacer(&s).unwrap();
assert!(json.contains("\"test\""));
assert!(json.contains("42"));
}
#[test]
fn u256_dec_string_zero() {
let w = U256DecString(U256::ZERO);
let json = serde_json::to_string(&w).unwrap();
assert_eq!(json, "\"0\"");
}
#[test]
fn u256_string_module_roundtrip_zero() {
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Wrapper {
#[serde(with = "u256_string")]
value: U256,
}
let w = Wrapper { value: U256::ZERO };
let json = serde_json::to_string(&w).unwrap();
assert!(json.contains("\"0\""));
let back: Wrapper = serde_json::from_str(&json).unwrap();
assert_eq!(back, w);
}
#[test]
fn u256_string_module_roundtrip_max() {
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Wrapper {
#[serde(with = "u256_string")]
value: U256,
}
let w = Wrapper { value: U256::MAX };
let json = serde_json::to_string(&w).unwrap();
let back: Wrapper = serde_json::from_str(&json).unwrap();
assert_eq!(back, w);
}
#[test]
fn u256_string_deserialize_invalid_returns_error() {
use serde::Deserialize;
#[derive(Deserialize)]
struct Wrapper {
#[serde(with = "u256_string")]
#[allow(dead_code, reason = "field is tested via deserialization failure")]
value: U256,
}
let result = serde_json::from_str::<Wrapper>(r#"{"value":"not-a-number"}"#);
assert!(result.is_err());
}
#[test]
fn u256_to_dec_string_via_serialize_with() {
use serde::Serialize;
#[derive(Serialize)]
struct Wrapper {
#[serde(serialize_with = "u256_to_dec_string")]
value: U256,
}
let w = Wrapper { value: U256::from(7777u64) };
let json = serde_json::to_string(&w).unwrap();
assert!(json.contains("\"7777\""));
}
#[test]
fn json_with_bigint_replacer_with_u256_field() {
use serde::Serialize;
#[derive(Serialize)]
struct WithU256 {
#[serde(serialize_with = "u256_to_dec_string")]
amount: U256,
}
let val = WithU256 { amount: U256::from(123u64) };
let json = json_with_bigint_replacer(&val).unwrap();
assert!(json.contains("\"123\""));
}
}