Merge rust-bitcoin/rust-bitcoin#4505: units: `serde` cleanup

980365097d Fix expecting string for amount types (Tobin C. Harding)
3658865a18 Fix expecting string for fee_rate (Tobin C. Harding)
d6940497fd Simplify fee_rate serde deserialize opt (Tobin C. Harding)
87d6f1718c Make serde attribute usage more terse (Tobin C. Harding)

Pull request description:

  Clean up the `serde` stuff for `FeeRate` and `Amount`. This is all pretty trivial.

ACKs for top commit:
  apoelstra:
    ACK 980365097d44fc8ebb8e0b1327058a59ae62a439; successfully ran local tests

Tree-SHA512: 70d3b5245f69c87b03ed2259bb6eefc93d075c6246f1fae3e4cc14934f41bbcf6cb6d69b3a3986b3b382bb00f3457a2f7be91e8b805823db4f802a086f2f27e4
This commit is contained in:
merge-script 2025-05-14 15:27:25 +00:00
commit 5533d3ee79
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
3 changed files with 35 additions and 44 deletions

View File

@ -13,11 +13,11 @@
//! //!
//! ``` //! ```
//! use serde::{Serialize, Deserialize}; //! use serde::{Serialize, Deserialize};
//! use bitcoin_units::Amount; //! use bitcoin_units::{amount, Amount};
//! //!
//! #[derive(Serialize, Deserialize)] //! #[derive(Serialize, Deserialize)]
//! pub struct HasAmount { //! pub struct HasAmount {
//! #[serde(with = "bitcoin_units::amount::serde::as_sat")] //! #[serde(with = "amount::serde::as_sat")]
//! pub amount: Amount, //! pub amount: Amount,
//! } //! }
//! ``` //! ```
@ -230,7 +230,7 @@ pub mod as_sat {
type Value = Option<X>; type Value = Option<X>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "An Option<{}64>", X::type_prefix(private::Token)) write!(formatter, "an Option<{}64>", X::type_prefix(private::Token))
} }
fn visit_none<E>(self) -> Result<Self::Value, E> fn visit_none<E>(self) -> Result<Self::Value, E>
@ -301,7 +301,7 @@ pub mod as_btc {
type Value = Option<X>; type Value = Option<X>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "An Option<f64>") write!(formatter, "an Option<f64>")
} }
fn visit_none<E>(self) -> Result<Self::Value, E> fn visit_none<E>(self) -> Result<Self::Value, E>
@ -372,7 +372,7 @@ pub mod as_str {
type Value = Option<X>; type Value = Option<X>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "An Option<String>") write!(formatter, "an Option<String>")
} }
fn visit_none<E>(self) -> Result<Self::Value, E> fn visit_none<E>(self) -> Result<Self::Value, E>
@ -396,6 +396,7 @@ pub mod as_str {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::amount;
#[test] #[test]
fn sanity_check() { fn sanity_check() {
@ -407,7 +408,7 @@ mod tests {
fn can_serde_as_sat() { fn can_serde_as_sat() {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct HasAmount { pub struct HasAmount {
#[serde(with = "crate::amount::serde::as_sat")] #[serde(with = "amount::serde::as_sat")]
pub amount: Amount, pub amount: Amount,
} }
@ -426,7 +427,7 @@ mod tests {
fn can_serde_as_btc() { fn can_serde_as_btc() {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct HasAmount { pub struct HasAmount {
#[serde(with = "crate::amount::serde::as_btc")] #[serde(with = "amount::serde::as_btc")]
pub amount: Amount, pub amount: Amount,
} }
@ -445,7 +446,7 @@ mod tests {
fn can_serde_as_str() { fn can_serde_as_str() {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct HasAmount { pub struct HasAmount {
#[serde(with = "crate::amount::serde::as_str")] #[serde(with = "amount::serde::as_str")]
pub amount: Amount, pub amount: Amount,
} }

View File

@ -14,11 +14,11 @@
//! //!
//! ``` //! ```
//! use serde::{Serialize, Deserialize}; //! use serde::{Serialize, Deserialize};
//! use bitcoin_units::FeeRate; //! use bitcoin_units::{fee_rate, FeeRate};
//! //!
//! #[derive(Serialize, Deserialize)] //! #[derive(Serialize, Deserialize)]
//! pub struct Foo { //! pub struct Foo {
//! #[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_kwu")] //! #[serde(with = "fee_rate::serde::as_sat_per_kwu")]
//! pub fee_rate: FeeRate, //! pub fee_rate: FeeRate,
//! } //! }
//! ``` //! ```
@ -50,7 +50,7 @@ pub mod as_sat_per_kwu {
use core::fmt; use core::fmt;
use serde::{de, Deserialize, Deserializer, Serializer}; use serde::{de, Deserializer, Serializer};
use crate::FeeRate; use crate::FeeRate;
@ -69,7 +69,7 @@ pub mod as_sat_per_kwu {
type Value = Option<FeeRate>; type Value = Option<FeeRate>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "An Option<FeeRate>") write!(f, "an Option<u64>")
} }
fn visit_none<E>(self) -> Result<Self::Value, E> fn visit_none<E>(self) -> Result<Self::Value, E>
@ -83,7 +83,7 @@ pub mod as_sat_per_kwu {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
Ok(Some(FeeRate::from_sat_per_kwu(u64::deserialize(d)?))) Ok(Some(super::deserialize(d)?))
} }
} }
d.deserialize_option(VisitOpt) d.deserialize_option(VisitOpt)
@ -121,9 +121,8 @@ pub mod as_sat_per_vb_floor {
use core::fmt; use core::fmt;
use serde::{de, Deserialize, Deserializer, Serializer}; use serde::{de, Deserializer, Serializer};
use crate::fee_rate::serde::OverflowError;
use crate::fee_rate::FeeRate; use crate::fee_rate::FeeRate;
#[allow(clippy::ref_option)] // API forced by serde. #[allow(clippy::ref_option)] // API forced by serde.
@ -141,7 +140,7 @@ pub mod as_sat_per_vb_floor {
type Value = Option<FeeRate>; type Value = Option<FeeRate>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "An Option<FeeRate>") write!(f, "an Option<u64>")
} }
fn visit_none<E>(self) -> Result<Self::Value, E> fn visit_none<E>(self) -> Result<Self::Value, E>
@ -155,11 +154,7 @@ pub mod as_sat_per_vb_floor {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
Ok(Some( Ok(Some(super::deserialize(d)?))
FeeRate::from_sat_per_vb(u64::deserialize(d)?)
.ok_or(OverflowError)
.map_err(serde::de::Error::custom)?,
))
} }
} }
d.deserialize_option(VisitOpt) d.deserialize_option(VisitOpt)
@ -197,9 +192,8 @@ pub mod as_sat_per_vb_ceil {
use core::fmt; use core::fmt;
use serde::{de, Deserialize, Deserializer, Serializer}; use serde::{de, Deserializer, Serializer};
use crate::fee_rate::serde::OverflowError;
use crate::fee_rate::FeeRate; use crate::fee_rate::FeeRate;
#[allow(clippy::ref_option)] // API forced by serde. #[allow(clippy::ref_option)] // API forced by serde.
@ -217,7 +211,7 @@ pub mod as_sat_per_vb_ceil {
type Value = Option<FeeRate>; type Value = Option<FeeRate>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "An Option<FeeRate>") write!(f, "an Option<u64>")
} }
fn visit_none<E>(self) -> Result<Self::Value, E> fn visit_none<E>(self) -> Result<Self::Value, E>
@ -231,11 +225,7 @@ pub mod as_sat_per_vb_ceil {
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
Ok(Some( Ok(Some(super::deserialize(d)?))
FeeRate::from_sat_per_vb(u64::deserialize(d)?)
.ok_or(OverflowError)
.map_err(serde::de::Error::custom)?,
))
} }
} }
d.deserialize_option(VisitOpt) d.deserialize_option(VisitOpt)

View File

@ -7,41 +7,41 @@
use bincode::serialize; use bincode::serialize;
use bitcoin_units::locktime::{absolute, relative}; use bitcoin_units::locktime::{absolute, relative};
use bitcoin_units::{Amount, BlockHeight, BlockInterval, FeeRate, SignedAmount, Weight}; use bitcoin_units::{amount, fee_rate, Amount, BlockHeight, BlockInterval, FeeRate, SignedAmount, Weight};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// A struct that includes all the types that implement or support `serde` traits. /// A struct that includes all the types that implement or support `serde` traits.
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct Serde { struct Serde {
#[serde(with = "bitcoin_units::amount::serde::as_sat")] #[serde(with = "amount::serde::as_sat")]
unsigned_as_sat: Amount, unsigned_as_sat: Amount,
#[serde(with = "bitcoin_units::amount::serde::as_btc")] #[serde(with = "amount::serde::as_btc")]
unsigned_as_btc: Amount, unsigned_as_btc: Amount,
#[serde(with = "bitcoin_units::amount::serde::as_sat::opt")] #[serde(with = "amount::serde::as_sat::opt")]
unsigned_opt_as_sat: Option<Amount>, unsigned_opt_as_sat: Option<Amount>,
#[serde(with = "bitcoin_units::amount::serde::as_btc::opt")] #[serde(with = "amount::serde::as_btc::opt")]
unsigned_opt_as_btc: Option<Amount>, unsigned_opt_as_btc: Option<Amount>,
#[serde(with = "bitcoin_units::amount::serde::as_sat")] #[serde(with = "amount::serde::as_sat")]
signed_as_sat: SignedAmount, signed_as_sat: SignedAmount,
#[serde(with = "bitcoin_units::amount::serde::as_btc")] #[serde(with = "amount::serde::as_btc")]
signed_as_btc: SignedAmount, signed_as_btc: SignedAmount,
#[serde(with = "bitcoin_units::amount::serde::as_sat::opt")] #[serde(with = "amount::serde::as_sat::opt")]
signed_opt_as_sat: Option<SignedAmount>, signed_opt_as_sat: Option<SignedAmount>,
#[serde(with = "bitcoin_units::amount::serde::as_btc::opt")] #[serde(with = "amount::serde::as_btc::opt")]
signed_opt_as_btc: Option<SignedAmount>, signed_opt_as_btc: Option<SignedAmount>,
#[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_vb_floor")] #[serde(with = "fee_rate::serde::as_sat_per_vb_floor")]
vb_floor: FeeRate, vb_floor: FeeRate,
#[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_vb_ceil")] #[serde(with = "fee_rate::serde::as_sat_per_vb_ceil")]
vb_ceil: FeeRate, vb_ceil: FeeRate,
#[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_kwu")] #[serde(with = "fee_rate::serde::as_sat_per_kwu")]
kwu: FeeRate, kwu: FeeRate,
#[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_vb_floor::opt")] #[serde(with = "fee_rate::serde::as_sat_per_vb_floor::opt")]
opt_vb_floor: Option<FeeRate>, opt_vb_floor: Option<FeeRate>,
#[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_vb_ceil::opt")] #[serde(with = "fee_rate::serde::as_sat_per_vb_ceil::opt")]
opt_vb_ceil: Option<FeeRate>, opt_vb_ceil: Option<FeeRate>,
#[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_kwu::opt")] #[serde(with = "fee_rate::serde::as_sat_per_kwu::opt")]
opt_kwu: Option<FeeRate>, opt_kwu: Option<FeeRate>,
a: BlockHeight, a: BlockHeight,