diff --git a/src/util/amount.rs b/src/util/amount.rs index a732c440..c9b7f3eb 100644 --- a/src/util/amount.rs +++ b/src/util/amount.rs @@ -524,6 +524,13 @@ impl FromStr for Amount { } } +impl ::std::iter::Sum for Amount { + fn sum>(iter: I) -> Self { + let sats: u64 = iter.map(|amt| amt.0).sum(); + Amount::from_sat(sats) + } +} + /// SignedAmount /// /// The [SignedAmount] type can be used to express Bitcoin amounts that supports @@ -849,6 +856,13 @@ impl FromStr for SignedAmount { } } +impl ::std::iter::Sum for SignedAmount { + fn sum>(iter: I) -> Self { + let sats: i64 = iter.map(|amt| amt.0).sum(); + SignedAmount::from_sat(sats) + } +} + #[cfg(feature = "serde")] pub mod serde { // methods are implementation of a standardized serde-specific signature @@ -1512,4 +1526,26 @@ mod tests { let value_without: serde_json::Value = serde_json::from_str("{}").unwrap(); assert_eq!(without, serde_json::from_value(value_without).unwrap()); } + + #[test] + fn sum_amounts() { + assert_eq!(Amount::from_sat(0), vec![].into_iter().sum::()); + assert_eq!(SignedAmount::from_sat(0), vec![].into_iter().sum::()); + + let amounts = vec![ + Amount::from_sat(42), + Amount::from_sat(1337), + Amount::from_sat(21) + ]; + let sum = amounts.into_iter().sum::(); + assert_eq!(Amount::from_sat(1400), sum); + + let amounts = vec![ + SignedAmount::from_sat(-42), + SignedAmount::from_sat(1337), + SignedAmount::from_sat(21) + ]; + let sum = amounts.into_iter().sum::(); + assert_eq!(SignedAmount::from_sat(1316), sum); + } }