diff --git a/ethers-solc/src/artifacts/mod.rs b/ethers-solc/src/artifacts/mod.rs index c08b64b2..d9005879 100644 --- a/ethers-solc/src/artifacts/mod.rs +++ b/ethers-solc/src/artifacts/mod.rs @@ -898,7 +898,7 @@ impl Serialize for LosslessMetadata { where S: Serializer, { - self.raw_metadata.serialize(serializer) + serializer.serialize_str(&self.raw_metadata) } } @@ -920,8 +920,8 @@ impl<'de> Deserialize<'de> for LosslessMetadata { where E: serde::de::Error, { - let raw_metadata = value.to_string(); let metadata = serde_json::from_str(value).map_err(serde::de::Error::custom)?; + let raw_metadata = value.to_string(); Ok(LosslessMetadata { raw_metadata, metadata }) } } @@ -2097,4 +2097,27 @@ mod tests { ]) ); } + + #[test] + fn test_lossless_metadata() { + #[derive(Debug, Serialize, Deserialize)] + #[serde(rename_all = "camelCase")] + pub struct Contract { + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "serde_helpers::json_string_opt" + )] + pub metadata: Option, + } + + let s = r#"{"metadata":"{\"compiler\":{\"version\":\"0.4.18+commit.9cf6e910\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"newOwner\":\"The address to transfer ownership to.\"}}},\"title\":\"Ownable\"},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"src/Contract.sol\":\"Ownable\"},\"libraries\":{},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[\":src/=src/\"]},\"sources\":{\"src/Contract.sol\":{\"keccak256\":\"0x3e0d611f53491f313ae035797ed7ecfd1dfd8db8fef8f82737e6f0cd86d71de7\",\"urls\":[\"bzzr://9c33025fa9d1b8389e4c7c9534a1d70fad91c6c2ad70eb5e4b7dc3a701a5f892\"]}},\"version\":1}"}"#; + + let value: serde_json::Value = serde_json::from_str(s).unwrap(); + let c: Contract = serde_json::from_value(value).unwrap(); + assert_eq!(c.metadata.as_ref().unwrap().raw_metadata, "{\"compiler\":{\"version\":\"0.4.18+commit.9cf6e910\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"constant\":true,\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"}],\"devdoc\":{\"methods\":{\"transferOwnership(address)\":{\"details\":\"Allows the current owner to transfer control of the contract to a newOwner.\",\"params\":{\"newOwner\":\"The address to transfer ownership to.\"}}},\"title\":\"Ownable\"},\"userdoc\":{\"methods\":{}}},\"settings\":{\"compilationTarget\":{\"src/Contract.sol\":\"Ownable\"},\"libraries\":{},\"optimizer\":{\"enabled\":true,\"runs\":1000000},\"remappings\":[\":src/=src/\"]},\"sources\":{\"src/Contract.sol\":{\"keccak256\":\"0x3e0d611f53491f313ae035797ed7ecfd1dfd8db8fef8f82737e6f0cd86d71de7\",\"urls\":[\"bzzr://9c33025fa9d1b8389e4c7c9534a1d70fad91c6c2ad70eb5e4b7dc3a701a5f892\"]}},\"version\":1}"); + + let value = serde_json::to_string(&c).unwrap(); + pretty_assertions::assert_eq!(s, value); + } } diff --git a/ethers-solc/src/artifacts/serde_helpers.rs b/ethers-solc/src/artifacts/serde_helpers.rs index 0e38ee3f..75e87ee5 100644 --- a/ethers-solc/src/artifacts/serde_helpers.rs +++ b/ethers-solc/src/artifacts/serde_helpers.rs @@ -41,7 +41,7 @@ where pub mod json_string_opt { use serde::{ de::{self, DeserializeOwned}, - ser, Deserialize, Deserializer, Serialize, Serializer, + Deserialize, Deserializer, Serialize, Serializer, }; pub fn serialize(value: &Option, serializer: S) -> Result @@ -50,8 +50,7 @@ pub mod json_string_opt { T: Serialize, { if let Some(value) = value { - let value = serde_json::to_string(value).map_err(ser::Error::custom)?; - serializer.serialize_str(&value) + value.serialize(serializer) } else { serializer.serialize_none() } diff --git a/ethers-solc/src/report/mod.rs b/ethers-solc/src/report/mod.rs index 4d33285f..4c7a572d 100644 --- a/ethers-solc/src/report/mod.rs +++ b/ethers-solc/src/report/mod.rs @@ -253,7 +253,7 @@ where CURRENT_STATE .try_with(|state| { let scoped = state.scoped.borrow_mut(); - f(&*scoped) + f(&scoped) }) .unwrap_or_else(|_| f(&Report::none())) }