Move CheckedSum trait to crate root

In order to add other types to CheckedSum, remove from the Amount
module.  In so doing, other types added to CheeckSum do not need to be
imported into Amount.
This commit is contained in:
yancy 2025-05-26 18:04:33 -05:00
parent 0432102472
commit 0dbcd09bbc
4 changed files with 24 additions and 22 deletions

View File

@ -204,14 +204,15 @@ pub mod amount {
#[rustfmt::skip] // Keep public re-exports separate. #[rustfmt::skip] // Keep public re-exports separate.
#[doc(inline)] #[doc(inline)]
pub use units::CheckedSum;
#[cfg(feature = "serde")]
pub use units::amount::serde;
pub use units::amount::{ pub use units::amount::{
Amount, CheckedSum, Denomination, Display, InvalidCharacterError, MissingDenominationError, Amount, Denomination, Display, InvalidCharacterError, MissingDenominationError,
MissingDigitsError, OutOfRangeError, ParseAmountError, ParseDenominationError, ParseError, MissingDigitsError, OutOfRangeError, ParseAmountError, ParseDenominationError, ParseError,
PossiblyConfusingDenominationError, SignedAmount, TooPreciseError, PossiblyConfusingDenominationError, SignedAmount, TooPreciseError,
UnknownDenominationError, UnknownDenominationError,
}; };
#[cfg(feature = "serde")]
pub use units::amount::serde;
impl Decodable for Amount { impl Decodable for Amount {
#[inline] #[inline]

View File

@ -26,6 +26,7 @@ use core::str::FromStr;
use arbitrary::{Arbitrary, Unstructured}; use arbitrary::{Arbitrary, Unstructured};
use self::error::{MissingDigitsKind, ParseAmountErrorInner, ParseErrorInner}; use self::error::{MissingDigitsKind, ParseAmountErrorInner, ParseErrorInner};
use crate::CheckedSum;
#[rustfmt::skip] // Keep public re-exports separate. #[rustfmt::skip] // Keep public re-exports separate.
#[doc(inline)] #[doc(inline)]
@ -593,13 +594,6 @@ enum DisplayStyle {
DynamicDenomination, DynamicDenomination,
} }
/// Calculates the sum over the iterator using checked arithmetic.
pub trait CheckedSum<R>: sealed::Sealed<R> {
/// Calculates the sum over the iterator using checked arithmetic. If an
/// overflow happens it returns [`None`].
fn checked_sum(self) -> Option<R>;
}
impl<T> CheckedSum<Amount> for T impl<T> CheckedSum<Amount> for T
where where
T: Iterator<Item = Amount>, T: Iterator<Item = Amount>,
@ -616,16 +610,6 @@ where
} }
} }
mod sealed {
use super::{Amount, SignedAmount};
/// Used to seal the `CheckedSum` trait
pub trait Sealed<A> {}
impl<T> Sealed<Amount> for T where T: Iterator<Item = Amount> {}
impl<T> Sealed<SignedAmount> for T where T: Iterator<Item = SignedAmount> {}
}
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for Denomination { impl<'a> Arbitrary<'a> for Denomination {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> { fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {

View File

@ -69,3 +69,20 @@ pub(crate) use self::result::OptionExt;
#[deprecated(since = "TBD", note = "use `BlockHeightInterval` instead")] #[deprecated(since = "TBD", note = "use `BlockHeightInterval` instead")]
#[doc(hidden)] #[doc(hidden)]
pub type BlockInterval = BlockHeightInterval; pub type BlockInterval = BlockHeightInterval;
/// Calculates the sum over the iterator using checked arithmetic.
pub trait CheckedSum<R>: sealed::Sealed<R> {
/// Calculates the sum over the iterator using checked arithmetic. If an
/// overflow happens it returns [`None`].
fn checked_sum(self) -> Option<R>;
}
mod sealed {
use super::{Amount, SignedAmount};
/// Used to seal the `CheckedSum` trait
pub trait Sealed<A> {}
impl<T> Sealed<Amount> for T where T: Iterator<Item = Amount> {}
impl<T> Sealed<SignedAmount> for T where T: Iterator<Item = SignedAmount> {}
}

View File

@ -15,7 +15,7 @@ use arbitrary::{Arbitrary, Unstructured};
use bitcoin_units::locktime::{absolute, relative}; // Typical usage is `absolute::Height`. use bitcoin_units::locktime::{absolute, relative}; // Typical usage is `absolute::Height`.
use bitcoin_units::{ use bitcoin_units::{
amount, block, fee_rate, locktime, parse, weight, Amount, BlockHeight, BlockInterval, BlockMtp, amount, block, fee_rate, locktime, parse, weight, Amount, BlockHeight, BlockInterval, BlockMtp,
BlockMtpInterval, BlockTime, FeeRate, SignedAmount, Weight, BlockMtpInterval, BlockTime, CheckedSum, FeeRate, SignedAmount, Weight,
}; };
/// A struct that includes all public non-error enums. /// A struct that includes all public non-error enums.
@ -272,7 +272,7 @@ fn regression_default() {
fn dyn_compatible() { fn dyn_compatible() {
// If this builds then traits are dyn compatible. // If this builds then traits are dyn compatible.
struct Traits { struct Traits {
a: Box<dyn amount::CheckedSum<Amount>>, a: Box<dyn CheckedSum<Amount>>,
// These traits are explicitly not dyn compatible. // These traits are explicitly not dyn compatible.
// b: Box<dyn amount::serde::SerdeAmount>, // b: Box<dyn amount::serde::SerdeAmount>,
// c: Box<dyn amount::serde::SerdeAmountForOpt>, // c: Box<dyn amount::serde::SerdeAmountForOpt>,