diff --git a/ethers-etherscan/src/utils.rs b/ethers-etherscan/src/utils.rs index 3107492a..5549b1a9 100644 --- a/ethers-etherscan/src/utils.rs +++ b/ethers-etherscan/src/utils.rs @@ -25,12 +25,12 @@ pub async fn lookup_compiler_version(version: &Version) -> Result { pub fn deserialize_address_opt<'de, D: Deserializer<'de>>( deserializer: D, ) -> std::result::Result, D::Error> { - let s = String::deserialize(deserializer)?; - if s.is_empty() { - Ok(None) - } else { - let addr: Address = s.parse().map_err(serde::de::Error::custom)?; - Ok(Some(addr)) + match Option::::deserialize(deserializer)? { + None => Ok(None), + Some(s) => match s.is_empty() { + true => Ok(None), + _ => Ok(Some(s.parse().map_err(serde::de::Error::custom)?)), + }, } } @@ -104,7 +104,7 @@ mod tests { #[test] fn can_deserialize_address_opt() { - #[derive(Deserialize)] + #[derive(serde::Serialize, Deserialize)] struct Test { #[serde(deserialize_with = "deserialize_address_opt")] address: Option
, @@ -115,6 +115,11 @@ mod tests { let de: Test = serde_json::from_str(json).unwrap(); assert_eq!(de.address, None); + // Round-trip the above + let json = serde_json::to_string(&de).unwrap(); + let de: Test = serde_json::from_str(&json).unwrap(); + assert_eq!(de.address, None); + // https://api.etherscan.io/api?module=contract&action=getsourcecode&address=0xDef1C0ded9bec7F1a1670819833240f027b25EfF let json = r#"{"address":"0x4af649ffde640ceb34b1afaba3e0bb8e9698cb01"}"#; let de: Test = serde_json::from_str(json).unwrap();