1use std::future::Future;
2use std::pin::Pin;
3
4use crate::stream::Stream;
5
6#[cfg(feature = "unstable")]
17#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
18pub trait Sum<A = Self>: Sized {
19 fn sum<'a, S>(stream: S) -> Pin<Box<dyn Future<Output = Self> + 'a>>
22 where
23 S: Stream<Item = A> + 'a;
24}
25
26use crate::stream::stream::StreamExt;
27use core::num::Wrapping;
28use core::ops::Add;
29
30macro_rules! integer_sum {
31 (@impls $zero: expr, $($a:ty)*) => ($(
32 impl Sum for $a {
33 fn sum<'a, S>(stream: S) -> Pin<Box<dyn Future<Output = Self>+ 'a>>
34 where
35 S: Stream<Item = $a> + 'a,
36 {
37 Box::pin(async move { stream.fold($zero, Add::add).await } )
38 }
39 }
40 impl<'a> Sum<&'a $a> for $a {
41 fn sum<'b, S>(stream: S) -> Pin<Box<dyn Future<Output = Self> + 'b>>
42 where
43 S: Stream<Item = &'a $a> + 'b,
44 {
45 Box::pin(async move { stream.fold($zero, Add::add).await } )
46 }
47 }
48 )*);
49 ($($a:ty)*) => (
50 integer_sum!(@impls 0, $($a)*);
51 integer_sum!(@impls Wrapping(0), $(Wrapping<$a>)*);
52 );
53}
54
55macro_rules! float_sum {
56 ($($a:ty)*) => ($(
57 impl Sum for $a {
58 fn sum<'a, S>(stream: S) -> Pin<Box<dyn Future<Output = Self> + 'a>>
59 where S: Stream<Item = $a> + 'a,
60 {
61 Box::pin(async move { stream.fold(0.0, |a, b| a + b).await } )
62 }
63 }
64 impl<'a> Sum<&'a $a> for $a {
65 fn sum<'b, S>(stream: S) -> Pin<Box<dyn Future<Output = Self> + 'b>>
66 where S: Stream<Item = &'a $a> + 'b,
67 {
68 Box::pin(async move { stream.fold(0.0, |a, b| a + b).await } )
69 }
70 }
71 )*);
72 ($($a:ty)*) => (
73 float_sum!(@impls 0.0, $($a)*);
74 float_sum!(@impls Wrapping(0.0), $(Wrapping<$a>)*);
75 );
76}
77
78integer_sum! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
79float_sum! { f32 f64 }