Merge rust-bitcoin/rust-bitcoin#3677: units: Implement `iter::Sum` for all types that implement `ops::Add`

433f70939c Implement iter::Sum for BlockInterval (Tobin C. Harding)
0369e64b56 Implement Sum for an iterator of references to amounts (Tobin C. Harding)
31f883ac00 Implement iter::Sum for FeeRate (Tobin C. Harding)

Pull request description:

  Enables summing an iterator of values. Note that this does not include either `LockTime`s. `absolute::LockTime` should not be added and for `relative::LockTime` we have https://github.com/rust-bitcoin/rust-bitcoin/issues/3676

  Close: #1638

ACKs for top commit:
  apoelstra:
    ACK 433f70939c3ecc10702ab6502e3f9bcd94dab739; successfully ran local tests; nice!
  sanket1729:
    utACK 433f70939c

Tree-SHA512: 1eda00f3bbbc61f795198ce8525a5a9b690478a8abc268da6d2e40de7d91decc28dd8211df0c6abeaf30148c7ec3907b85e3c5351972c354590569840e84d562
This commit is contained in:
merge-script 2024-11-29 13:28:30 +00:00
commit 85d1eb8289
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
5 changed files with 57 additions and 2 deletions

View File

@ -457,6 +457,16 @@ impl core::iter::Sum for SignedAmount {
}
}
impl<'a> core::iter::Sum<&'a SignedAmount> for SignedAmount {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = &'a SignedAmount>,
{
let sats: i64 = iter.map(|amt| amt.0).sum();
SignedAmount::from_sat(sats)
}
}
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for SignedAmount {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {

View File

@ -825,8 +825,8 @@ fn serde_as_sat_opt() {
#[test]
fn sum_amounts() {
assert_eq!(Amount::from_sat(0), [].into_iter().sum::<Amount>());
assert_eq!(SignedAmount::from_sat(0), [].into_iter().sum::<SignedAmount>());
assert_eq!(Amount::from_sat(0), [].iter().sum::<Amount>());
assert_eq!(SignedAmount::from_sat(0), [].iter().sum::<SignedAmount>());
let amounts = [Amount::from_sat(42), Amount::from_sat(1337), Amount::from_sat(21)];
let sum = amounts.into_iter().sum::<Amount>();

View File

@ -444,6 +444,16 @@ impl core::iter::Sum for Amount {
}
}
impl<'a> core::iter::Sum<&'a Amount> for Amount {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = &'a Amount>,
{
let sats: u64 = iter.map(|amt| amt.0).sum();
Amount::from_sat(sats)
}
}
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for Amount {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {

View File

@ -231,6 +231,23 @@ impl ops::SubAssign<BlockInterval> for BlockInterval {
fn sub_assign(&mut self, rhs: BlockInterval) { self.0 = self.to_u32() - rhs.to_u32(); }
}
impl core::iter::Sum for BlockInterval {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
let sum = iter.map(|interval| interval.0).sum();
BlockInterval::from_u32(sum)
}
}
impl<'a> core::iter::Sum<&'a BlockInterval> for BlockInterval {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = &'a BlockInterval>,
{
let sum = iter.map(|interval| interval.0).sum();
BlockInterval::from_u32(sum)
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -267,6 +267,24 @@ impl SubAssign<&FeeRate> for FeeRate {
fn sub_assign(&mut self, rhs: &FeeRate) { self.0 -= rhs.0 }
}
impl core::iter::Sum for FeeRate {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = Self>,
{
FeeRate::from_sat_per_kwu(iter.map(FeeRate::to_sat_per_kwu).sum())
}
}
impl<'a> core::iter::Sum<&'a FeeRate> for FeeRate {
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item = &'a FeeRate>,
{
FeeRate::from_sat_per_kwu(iter.map(|f| FeeRate::to_sat_per_kwu(*f)).sum())
}
}
crate::impl_parse_str_from_int_infallible!(FeeRate, u64, from_sat_per_kwu);
#[cfg(test)]