async_std/stream/
product.rs1use std::pin::Pin;
2use std::future::Future;
3
4use crate::stream::Stream;
5
6#[cfg(feature = "unstable")]
17#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
18pub trait Product<A = Self>: Sized {
19 fn product<'a, S>(stream: S) -> Pin<Box<dyn Future<Output = Self> + 'a>>
22 where
23 S: Stream<Item = A> + 'a;
24}
25
26use core::ops::Mul;
27use core::num::Wrapping;
28use crate::stream::stream::StreamExt;
29
30macro_rules! integer_product {
31 (@impls $one: expr, $($a:ty)*) => ($(
32 impl Product for $a {
33 fn product<'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($one, Mul::mul).await } )
38 }
39 }
40 impl<'a> Product<&'a $a> for $a {
41 fn product<'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($one, Mul::mul).await } )
46 }
47 }
48 )*);
49 ($($a:ty)*) => (
50 integer_product!(@impls 1, $($a)*);
51 integer_product!(@impls Wrapping(1), $(Wrapping<$a>)*);
52 );
53}
54
55macro_rules! float_product {
56 ($($a:ty)*) => ($(
57 impl Product for $a {
58 fn product<'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(1.0, |a, b| a * b).await } )
62 }
63 }
64 impl<'a> Product<&'a $a> for $a {
65 fn product<'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(1.0, |a, b| a * b).await } )
69 }
70 }
71 )*);
72 ($($a:ty)*) => (
73 float_product!($($a)*);
74 float_product!($(Wrapping<$a>)*);
75 );
76}
77
78integer_product!{ i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
79float_product!{ f32 f64 }