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.
#[doc(inline)]
pub use units::CheckedSum;
#[cfg(feature = "serde")]
pub use units::amount::serde;
pub use units::amount::{
Amount, CheckedSum, Denomination, Display, InvalidCharacterError, MissingDenominationError,
Amount, Denomination, Display, InvalidCharacterError, MissingDenominationError,
MissingDigitsError, OutOfRangeError, ParseAmountError, ParseDenominationError, ParseError,
PossiblyConfusingDenominationError, SignedAmount, TooPreciseError,
UnknownDenominationError,
};
#[cfg(feature = "serde")]
pub use units::amount::serde;
impl Decodable for Amount {
#[inline]

View File

@ -26,6 +26,7 @@ use core::str::FromStr;
use arbitrary::{Arbitrary, Unstructured};
use self::error::{MissingDigitsKind, ParseAmountErrorInner, ParseErrorInner};
use crate::CheckedSum;
#[rustfmt::skip] // Keep public re-exports separate.
#[doc(inline)]
@ -593,13 +594,6 @@ enum DisplayStyle {
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
where
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")]
impl<'a> Arbitrary<'a> for Denomination {
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")]
#[doc(hidden)]
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::{
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.
@ -272,7 +272,7 @@ fn regression_default() {
fn dyn_compatible() {
// If this builds then traits are dyn compatible.
struct Traits {
a: Box<dyn amount::CheckedSum<Amount>>,
a: Box<dyn CheckedSum<Amount>>,
// These traits are explicitly not dyn compatible.
// b: Box<dyn amount::serde::SerdeAmount>,
// c: Box<dyn amount::serde::SerdeAmountForOpt>,