locktime: unify serde impls

This commit is contained in:
Andrew Poelstra 2022-12-11 17:17:17 +00:00
parent 32afe5ae48
commit 74ff4946e4
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
3 changed files with 38 additions and 2 deletions

View File

@ -179,8 +179,6 @@ impl fmt::UpperHex for PackedLockTime {
/// ``` /// ```
#[allow(clippy::derive_ord_xor_partial_ord)] #[allow(clippy::derive_ord_xor_partial_ord)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
pub enum LockTime { pub enum LockTime {
/// A block height lock time value. /// A block height lock time value.
/// ///
@ -440,6 +438,44 @@ impl Decodable for LockTime {
} }
} }
#[cfg(feature = "serde")]
impl serde::Serialize for LockTime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u32(self.to_consensus_u32())
}
}
#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for LockTime {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = u32;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { f.write_str("a u32") }
// We cannot just implement visit_u32 because JSON (among other things) always
// calls visit_u64, even when called from Deserializer::deserialize_u32. The
// other visit_u*s have default implementations that forward to visit_u64.
fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<u32, E> {
use core::convert::TryInto;
v.try_into().map_err(|_| E::invalid_value(serde::de::Unexpected::Unsigned(v), &"a 32-bit number"))
}
// Also do the signed version, just for good measure.
fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<u32, E> {
use core::convert::TryInto;
v.try_into().map_err(|_| E::invalid_value(serde::de::Unexpected::Signed(v), &"a 32-bit number"))
}
}
deserializer.deserialize_u32(Visitor).map(LockTime::from_consensus)
}
}
/// An absolute block height, guaranteed to always contain a valid height value. /// An absolute block height, guaranteed to always contain a valid height value.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]