Use efficient serialization for non-human-readable formats

This commit is contained in:
Nadav Ivgi 2021-01-06 00:01:21 +02:00
parent b70361370b
commit 4a7cf34eeb
No known key found for this signature in database
GPG Key ID: 81F6104CD0F150FC
3 changed files with 27 additions and 3 deletions

View File

@ -34,5 +34,6 @@ serde = { version = "1", features = [ "derive" ], optional = true }
serde_json = "<1.0.45" serde_json = "<1.0.45"
serde_test = "1" serde_test = "1"
secp256k1 = { version = "0.20.0", features = [ "recovery", "rand-std" ] } secp256k1 = { version = "0.20.0", features = [ "recovery", "rand-std" ] }
bincode = "1.3.1"
# We need to pin ryu (transitive dep from serde_json) to stay compatible with Rust 1.22.0 # We need to pin ryu (transitive dep from serde_json) to stay compatible with Rust 1.22.0
ryu = "<1.0.5" ryu = "<1.0.5"

View File

@ -47,6 +47,7 @@ pub extern crate bech32;
#[cfg(feature = "serde")] #[macro_use] extern crate serde; #[cfg(feature = "serde")] #[macro_use] extern crate serde;
#[cfg(all(test, feature = "serde"))] extern crate serde_json; #[cfg(all(test, feature = "serde"))] extern crate serde_json;
#[cfg(all(test, feature = "serde"))] extern crate serde_test; #[cfg(all(test, feature = "serde"))] extern crate serde_test;
#[cfg(all(test, feature = "serde"))] extern crate bincode;
#[cfg(all(test, feature = "unstable"))] extern crate test; #[cfg(all(test, feature = "unstable"))] extern crate test;
#[cfg(target_pointer_width = "16")] #[cfg(target_pointer_width = "16")]

View File

@ -436,7 +436,12 @@ macro_rules! construct_uint {
S: $crate::serde::Serializer, S: $crate::serde::Serializer,
{ {
use $crate::hashes::hex::ToHex; use $crate::hashes::hex::ToHex;
serializer.serialize_str(&self.to_be_bytes().to_hex()) let bytes = self.to_be_bytes();
if serializer.is_human_readable() {
serializer.serialize_str(&bytes.to_hex())
} else {
serializer.serialize_bytes(&bytes)
}
} }
} }
@ -453,7 +458,7 @@ macro_rules! construct_uint {
type Value = $name; type Value = $name;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "hex string with {} characters ({} bytes", $n_words * 8 * 2, $n_words * 8) write!(f, "{} bytes or a hex string with {} characters", $n_words * 8, $n_words * 8 * 2)
} }
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
@ -465,8 +470,21 @@ macro_rules! construct_uint {
$name::from_be_slice(&bytes) $name::from_be_slice(&bytes)
.map_err(|_| de::Error::invalid_length(bytes.len() * 2, &self)) .map_err(|_| de::Error::invalid_length(bytes.len() * 2, &self))
} }
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
$name::from_be_slice(bytes)
.map_err(|_| de::Error::invalid_length(bytes.len(), &self))
} }
}
if deserializer.is_human_readable() {
deserializer.deserialize_str(Visitor) deserializer.deserialize_str(Visitor)
} else {
deserializer.deserialize_bytes(Visitor)
}
} }
} }
); );
@ -703,6 +721,10 @@ mod tests {
let json = format!("\"{}\"", hex); let json = format!("\"{}\"", hex);
assert_eq!(::serde_json::to_string(&uint).unwrap(), json); assert_eq!(::serde_json::to_string(&uint).unwrap(), json);
assert_eq!(::serde_json::from_str::<Uint256>(&json).unwrap(), uint); assert_eq!(::serde_json::from_str::<Uint256>(&json).unwrap(), uint);
let bin_encoded = ::bincode::serialize(&uint).unwrap();
let bin_decoded: Uint256 = ::bincode::deserialize(&bin_encoded).unwrap();
assert_eq!(bin_decoded, uint);
}; };
check( check(