fix hex be opt

This commit is contained in:
realbigsean 2022-12-01 14:20:50 -05:00
parent 8102a01085
commit c96234f38c
No known key found for this signature in database
GPG Key ID: B372B64D866BF8CC

View File

@ -1,6 +1,6 @@
use ethereum_types::U256; use ethereum_types::U256;
use serde::de::Visitor; use serde::de::{Error, Visitor};
use serde::{de, Deserializer, Serialize, Serializer}; use serde::{de, Deserializer, Serialize, Serializer};
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
@ -15,12 +15,26 @@ where
pub struct U256Visitor; pub struct U256Visitor;
impl<'de> Visitor<'de> for U256Visitor { impl<'de> Visitor<'de> for U256Visitor {
type Value = String; type Value = Option<String>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a well formatted hex string") formatter.write_str("a well formatted hex string")
} }
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_string(U256Visitor)
}
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: Error,
{
Ok(None)
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where where
E: de::Error, E: de::Error,
@ -35,11 +49,11 @@ impl<'de> Visitor<'de> for U256Visitor {
stripped stripped
))) )))
} else if stripped == "0" { } else if stripped == "0" {
Ok(value.to_string()) Ok(Some(value.to_string()))
} else if stripped.starts_with('0') { } else if stripped.starts_with('0') {
Err(de::Error::custom("cannot have leading zero")) Err(de::Error::custom("cannot have leading zero"))
} else { } else {
Ok(value.to_string()) Ok(Some(value.to_string()))
} }
} }
} }
@ -48,13 +62,14 @@ pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let decoded = deserializer.deserialize_string(U256Visitor)?; let decoded = deserializer.deserialize_option(U256Visitor)?;
Some( decoded
U256::from_str(&decoded) .map(|decoded| {
.map_err(|e| de::Error::custom(format!("Invalid U256 string: {}", e))), U256::from_str(&decoded)
) .map_err(|e| de::Error::custom(format!("Invalid U256 string: {}", e)))
.transpose() })
.transpose()
} }
#[cfg(test)] #[cfg(test)]
@ -161,6 +176,10 @@ mod test {
val: Some(U256::max_value()) val: Some(U256::max_value())
}, },
); );
assert_eq!(
serde_json::from_str::<Wrapper>("null").unwrap(),
Wrapper { val: None },
);
serde_json::from_str::<Wrapper>("\"0x\"").unwrap_err(); serde_json::from_str::<Wrapper>("\"0x\"").unwrap_err();
serde_json::from_str::<Wrapper>("\"0x0400\"").unwrap_err(); serde_json::from_str::<Wrapper>("\"0x0400\"").unwrap_err();
serde_json::from_str::<Wrapper>("\"400\"").unwrap_err(); serde_json::from_str::<Wrapper>("\"400\"").unwrap_err();