Merge rust-bitcoin/rust-bitcoin#4506: units: Manually implement serde traits
e2d03fef72
units: Manually implement serde traits (Tobin C. Harding)
Pull request description:
For types that have private inner fields we would like to manually implement `serde` traits instead of deriving them.
This hardens the crate against making future mistakes if we want to change the inner fields.
Do so for:
- `Weight`
- `BlockTime`
- `NumberOfBlocks`
- `NumberOf512seconds`
ACKs for top commit:
apoelstra:
ACK e2d03fef72f4fcbdacd1cbecc0c2dddfbdeb3031; successfully ran local tests
Tree-SHA512: 6d3cc4106e44e08d59f8da6f8f3285923408ed05d1c0b2f6f2d83a22718744a38bf67381177856b5713810a5f5318d929daa2d12447c722628e0576fcd075e3d
This commit is contained in:
commit
1b709eb460
|
@ -8,7 +8,7 @@ use core::fmt;
|
|||
#[cfg(feature = "arbitrary")]
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
#[deprecated(since = "TBD", note = "use `NumberOfBlocks` instead")]
|
||||
#[doc(hidden)]
|
||||
|
@ -16,7 +16,6 @@ pub type Height = NumberOfBlocks;
|
|||
|
||||
/// A relative lock time lock-by-blockheight value.
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct NumberOfBlocks(u16);
|
||||
|
||||
impl NumberOfBlocks {
|
||||
|
@ -92,6 +91,28 @@ impl fmt::Display for NumberOfBlocks {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for NumberOfBlocks {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
u16::serialize(&self.to_height(), s)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> Deserialize<'de> for NumberOfBlocks {
|
||||
#[inline]
|
||||
fn deserialize<D>(d: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Ok(Self::from_height(u16::deserialize(d)?))
|
||||
}
|
||||
}
|
||||
|
||||
#[deprecated(since = "TBD", note = "use `NumberOf512Seconds` instead")]
|
||||
#[doc(hidden)]
|
||||
pub type Time = NumberOf512Seconds;
|
||||
|
@ -100,7 +121,6 @@ pub type Time = NumberOf512Seconds;
|
|||
///
|
||||
/// For BIP 68 relative lock-by-blocktime locks, time is measured in 512 second intervals.
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct NumberOf512Seconds(u16);
|
||||
|
||||
impl NumberOf512Seconds {
|
||||
|
@ -213,6 +233,28 @@ impl fmt::Display for NumberOf512Seconds {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for NumberOf512Seconds {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
u16::serialize(&self.to_512_second_intervals(), s)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> Deserialize<'de> for NumberOf512Seconds {
|
||||
#[inline]
|
||||
fn deserialize<D>(d: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Ok(Self::from_512_second_intervals(u16::deserialize(d)?))
|
||||
}
|
||||
}
|
||||
|
||||
/// Error returned when the input time in seconds was too large to be encoded to a 16 bit 512 second interval.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct TimeOverflowError {
|
||||
|
|
|
@ -9,11 +9,10 @@
|
|||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
mod encapsulate {
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// A Bitcoin block timestamp.
|
||||
///
|
||||
/// > Each block contains a Unix time timestamp. In addition to serving as a source of variation for
|
||||
|
@ -27,7 +26,6 @@ mod encapsulate {
|
|||
///
|
||||
/// ref: <https://en.bitcoin.it/wiki/Block_timestamp>
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct BlockTime(u32);
|
||||
|
||||
impl BlockTime {
|
||||
|
@ -53,6 +51,28 @@ impl From<BlockTime> for u32 {
|
|||
fn from(t: BlockTime) -> Self { t.to_u32() }
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for BlockTime {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
u32::serialize(&self.to_u32(), s)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> Deserialize<'de> for BlockTime {
|
||||
#[inline]
|
||||
fn deserialize<D>(d: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Ok(Self::from_u32(u32::deserialize(d)?))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> Arbitrary<'a> for BlockTime {
|
||||
#[inline]
|
||||
|
|
|
@ -7,21 +7,19 @@ use core::{fmt, ops};
|
|||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
use arbitrary::{Arbitrary, Unstructured};
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
/// The factor that non-witness serialization data is multiplied by during weight calculation.
|
||||
pub const WITNESS_SCALE_FACTOR: usize = 4;
|
||||
|
||||
mod encapsulate {
|
||||
#[cfg(feature = "serde")]
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// The weight of a transaction or block.
|
||||
///
|
||||
/// This is an integer newtype representing [`Weight`] in `wu`. It provides protection
|
||||
/// against mixing up types as well as basic formatting features.
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
pub struct Weight(u64);
|
||||
|
||||
impl Weight {
|
||||
|
@ -263,6 +261,28 @@ impl<'a> core::iter::Sum<&'a Weight> for Weight {
|
|||
|
||||
crate::impl_parse_str_from_int_infallible!(Weight, u64, from_wu);
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl Serialize for Weight {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
u64::serialize(&self.to_wu(), s)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> Deserialize<'de> for Weight {
|
||||
#[inline]
|
||||
fn deserialize<D>(d: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Ok(Self::from_wu(u64::deserialize(d)?))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "arbitrary")]
|
||||
impl<'a> Arbitrary<'a> for Weight {
|
||||
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
|
||||
|
|
Loading…
Reference in New Issue