diff --git a/Cargo-minimal.lock b/Cargo-minimal.lock index 4ca2d3d5b..322bc5dfe 100644 --- a/Cargo-minimal.lock +++ b/Cargo-minimal.lock @@ -129,6 +129,7 @@ name = "bitcoin-units" version = "0.2.0" dependencies = [ "arbitrary", + "bincode", "bitcoin-internals", "serde", "serde_json", diff --git a/Cargo-recent.lock b/Cargo-recent.lock index c4fd9762b..95a076c6e 100644 --- a/Cargo-recent.lock +++ b/Cargo-recent.lock @@ -128,6 +128,7 @@ name = "bitcoin-units" version = "0.2.0" dependencies = [ "arbitrary", + "bincode", "bitcoin-internals", "serde", "serde_json", diff --git a/units/Cargo.toml b/units/Cargo.toml index 021ed1f58..d0368dace 100644 --- a/units/Cargo.toml +++ b/units/Cargo.toml @@ -25,6 +25,7 @@ arbitrary = { version = "1.4", optional = true } [dev-dependencies] internals = { package = "bitcoin-internals", version = "0.4.0", features = ["test-serde"] } +bincode = "1.3.1" serde_test = "1.0" serde_json = "1.0" diff --git a/units/tests/data/serde_bincode b/units/tests/data/serde_bincode new file mode 100644 index 000000000..51d7dc1d0 Binary files /dev/null and b/units/tests/data/serde_bincode differ diff --git a/units/tests/serde.rs b/units/tests/serde.rs new file mode 100644 index 000000000..d807bcc76 --- /dev/null +++ b/units/tests/serde.rs @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: CC0-1.0 + +//! Test the `serde` implementations for types in `units`. + +#![cfg(feature = "alloc")] +#![cfg(feature = "serde")] + +use bincode::serialize; +use bitcoin_units::locktime::{absolute, relative}; +use bitcoin_units::{Amount, BlockHeight, BlockInterval, FeeRate, SignedAmount, Weight}; +use serde::{Deserialize, Serialize}; + +/// A struct that includes all the types that implement or support `serde` traits. +#[derive(Debug, Serialize, Deserialize)] +struct Serde { + #[serde(with = "bitcoin_units::amount::serde::as_sat")] + unsigned_as_sat: Amount, + #[serde(with = "bitcoin_units::amount::serde::as_btc")] + unsigned_as_btc: Amount, + #[serde(with = "bitcoin_units::amount::serde::as_sat::opt")] + unsigned_opt_as_sat: Option, + #[serde(with = "bitcoin_units::amount::serde::as_btc::opt")] + unsigned_opt_as_btc: Option, + + #[serde(with = "bitcoin_units::amount::serde::as_sat")] + signed_as_sat: SignedAmount, + #[serde(with = "bitcoin_units::amount::serde::as_btc")] + signed_as_btc: SignedAmount, + #[serde(with = "bitcoin_units::amount::serde::as_sat::opt")] + signed_opt_as_sat: Option, + #[serde(with = "bitcoin_units::amount::serde::as_btc::opt")] + signed_opt_as_btc: Option, + + #[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_vb_floor")] + vb_floor: FeeRate, + #[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_vb_ceil")] + vb_ceil: FeeRate, + #[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_kwu")] + kwu: FeeRate, + #[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_vb_floor::opt")] + opt_vb_floor: Option, + #[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_vb_ceil::opt")] + opt_vb_ceil: Option, + #[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_kwu::opt")] + opt_kwu: Option, + + a: BlockHeight, + b: BlockInterval, + c: absolute::Height, + d: absolute::Time, + e: relative::Height, + f: relative::Time, + g: Weight, +} + +impl Serde { + /// Constructs an arbitrary instance. + fn new() -> Self { + Self { + unsigned_as_sat: Amount::MAX, + unsigned_as_btc: Amount::MAX, + + unsigned_opt_as_sat: Some(Amount::MAX), + unsigned_opt_as_btc: Some(Amount::MAX), + + signed_as_sat: SignedAmount::MAX, + signed_as_btc: SignedAmount::MAX, + + signed_opt_as_sat: Some(SignedAmount::MAX), + signed_opt_as_btc: Some(SignedAmount::MAX), + + vb_floor: FeeRate::BROADCAST_MIN, + vb_ceil: FeeRate::BROADCAST_MIN, + kwu: FeeRate::BROADCAST_MIN, + + opt_vb_floor: Some(FeeRate::BROADCAST_MIN), + opt_vb_ceil: Some(FeeRate::BROADCAST_MIN), + opt_kwu: Some(FeeRate::BROADCAST_MIN), + + a: BlockHeight::MAX, + b: BlockInterval::MAX, + c: absolute::Height::MAX, + d: absolute::Time::MAX, + e: relative::Height::MAX, + f: relative::Time::MAX, + g: Weight::MAX, + } + } +} + +#[test] +fn serde_regression() { + let t = Serde::new(); + let got = serialize(&t).unwrap(); + let want = include_bytes!("data/serde_bincode"); + assert_eq!(got, want); +}