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 bitcoin_units::Amount;
//! use bitcoin_units::{amount, Amount};
//!
//! #[derive(Serialize, Deserialize)]
//! pub struct HasAmount {
//! #[serde(with = "bitcoin_units::amount::serde::as_sat")]
//! #[serde(with = "amount::serde::as_sat")]
//! pub amount: Amount,
//! }
//! ```
@ -230,7 +230,7 @@ pub mod as_sat {
type Value = Option<X>;
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>
@ -301,7 +301,7 @@ pub mod as_btc {
type Value = Option<X>;
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>
@ -372,7 +372,7 @@ pub mod as_str {
type Value = Option<X>;
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>
@ -396,6 +396,7 @@ pub mod as_str {
#[cfg(test)]
mod tests {
use super::*;
use crate::amount;
#[test]
fn sanity_check() {
@ -407,7 +408,7 @@ mod tests {
fn can_serde_as_sat() {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct HasAmount {
#[serde(with = "crate::amount::serde::as_sat")]
#[serde(with = "amount::serde::as_sat")]
pub amount: Amount,
}
@ -426,7 +427,7 @@ mod tests {
fn can_serde_as_btc() {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct HasAmount {
#[serde(with = "crate::amount::serde::as_btc")]
#[serde(with = "amount::serde::as_btc")]
pub amount: Amount,
}
@ -445,7 +446,7 @@ mod tests {
fn can_serde_as_str() {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct HasAmount {
#[serde(with = "crate::amount::serde::as_str")]
#[serde(with = "amount::serde::as_str")]
pub amount: Amount,
}

View File

@ -14,11 +14,11 @@
//!
//! ```
//! use serde::{Serialize, Deserialize};
//! use bitcoin_units::FeeRate;
//! use bitcoin_units::{fee_rate, FeeRate};
//!
//! #[derive(Serialize, Deserialize)]
//! 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,
//! }
//! ```
@ -50,7 +50,7 @@ pub mod as_sat_per_kwu {
use core::fmt;
use serde::{de, Deserialize, Deserializer, Serializer};
use serde::{de, Deserializer, Serializer};
use crate::FeeRate;
@ -69,7 +69,7 @@ pub mod as_sat_per_kwu {
type Value = Option<FeeRate>;
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>
@ -83,7 +83,7 @@ pub mod as_sat_per_kwu {
where
D: Deserializer<'de>,
{
Ok(Some(FeeRate::from_sat_per_kwu(u64::deserialize(d)?)))
Ok(Some(super::deserialize(d)?))
}
}
d.deserialize_option(VisitOpt)
@ -121,9 +121,8 @@ pub mod as_sat_per_vb_floor {
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;
#[allow(clippy::ref_option)] // API forced by serde.
@ -141,7 +140,7 @@ pub mod as_sat_per_vb_floor {
type Value = Option<FeeRate>;
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>
@ -155,11 +154,7 @@ pub mod as_sat_per_vb_floor {
where
D: Deserializer<'de>,
{
Ok(Some(
FeeRate::from_sat_per_vb(u64::deserialize(d)?)
.ok_or(OverflowError)
.map_err(serde::de::Error::custom)?,
))
Ok(Some(super::deserialize(d)?))
}
}
d.deserialize_option(VisitOpt)
@ -197,9 +192,8 @@ pub mod as_sat_per_vb_ceil {
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;
#[allow(clippy::ref_option)] // API forced by serde.
@ -217,7 +211,7 @@ pub mod as_sat_per_vb_ceil {
type Value = Option<FeeRate>;
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>
@ -231,11 +225,7 @@ pub mod as_sat_per_vb_ceil {
where
D: Deserializer<'de>,
{
Ok(Some(
FeeRate::from_sat_per_vb(u64::deserialize(d)?)
.ok_or(OverflowError)
.map_err(serde::de::Error::custom)?,
))
Ok(Some(super::deserialize(d)?))
}
}
d.deserialize_option(VisitOpt)

View File

@ -7,41 +7,41 @@
use bincode::serialize;
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};
/// 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")]
#[serde(with = "amount::serde::as_sat")]
unsigned_as_sat: Amount,
#[serde(with = "bitcoin_units::amount::serde::as_btc")]
#[serde(with = "amount::serde::as_btc")]
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>,
#[serde(with = "bitcoin_units::amount::serde::as_btc::opt")]
#[serde(with = "amount::serde::as_btc::opt")]
unsigned_opt_as_btc: Option<Amount>,
#[serde(with = "bitcoin_units::amount::serde::as_sat")]
#[serde(with = "amount::serde::as_sat")]
signed_as_sat: SignedAmount,
#[serde(with = "bitcoin_units::amount::serde::as_btc")]
#[serde(with = "amount::serde::as_btc")]
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>,
#[serde(with = "bitcoin_units::amount::serde::as_btc::opt")]
#[serde(with = "amount::serde::as_btc::opt")]
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,
#[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,
#[serde(with = "bitcoin_units::fee_rate::serde::as_sat_per_kwu")]
#[serde(with = "fee_rate::serde::as_sat_per_kwu")]
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>,
#[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>,
#[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>,
a: BlockHeight,