From 0b14571073f749a8aecf591b751f0d3a71cdf741 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Tue, 22 Mar 2022 09:56:09 +0100 Subject: [PATCH] Witness human-readable serde Previous implementations of Witness (and Vec>) serde serialization didn't support human-readable representations. This resulted in long unreadable JSON/YAML byte arrays, which were especially ugly when pretty-printed (a line per each byte). Co-authored-by: Tobin C. Harding --- src/blockdata/witness.rs | 59 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/src/blockdata/witness.rs b/src/blockdata/witness.rs index 92f356dd5b..5ee5c9d715 100644 --- a/src/blockdata/witness.rs +++ b/src/blockdata/witness.rs @@ -279,8 +279,20 @@ impl serde::Serialize for Witness { where S: serde::Serializer, { - let vec: Vec<_> = self.to_vec(); - serde::Serialize::serialize(&vec, serializer) + use hashes::hex::ToHex; + use serde::ser::SerializeSeq; + + let human_readable = serializer.is_human_readable(); + let mut seq = serializer.serialize_seq(Some(self.witness_elements))?; + + for elem in self.iter() { + if human_readable { + seq.serialize_element(&elem.to_hex())?; + } else { + seq.serialize_element(&elem)?; + } + } + seq.end() } } @@ -290,8 +302,47 @@ impl<'de> serde::Deserialize<'de> for Witness { where D: serde::Deserializer<'de>, { - let vec: Vec> = serde::Deserialize::deserialize(deserializer)?; - Ok(Witness::from_vec(vec)) + struct Visitor; // Human-readable visitor. + impl<'de> serde::de::Visitor<'de> for Visitor + { + type Value = Witness; + + fn expecting(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { + write!(f, "a sequence of hex arrays") + } + + fn visit_seq>(self, mut a: A) -> Result + { + use hashes::hex::FromHex; + use hashes::hex::Error::*; + + let mut ret = Vec::new(); + while let Some(elem) = a.next_element::()? { + let vec = Vec::::from_hex(&elem).map_err(|e| { + match e { + InvalidChar(c) => { + let c = core::char::from_u32(c as u32).unwrap_or('-'); + serde::de::Error::invalid_value(serde::de::Unexpected::Char(c), &"a valid hex character") + } + OddLengthString(len) => serde::de::Error::invalid_length(len, &"an even length string"), + InvalidLength(expected, got) => { + let exp = format!("expected length: {}", expected); + serde::de::Error::invalid_length(got, &exp.as_str()) + } + } + })?; + ret.push(vec); + } + Ok(Witness::from_vec(ret)) + } + } + + if deserializer.is_human_readable() { + deserializer.deserialize_seq(Visitor) + } else { + let vec: Vec> = serde::Deserialize::deserialize(deserializer)?; + Ok(Witness::from_vec(vec)) + } } }