1+ use std:: pin:: Pin ;
2+
13use crate :: future:: Future ;
24use crate :: stream:: Stream ;
35
4- /// Trait to represent types that can be created by productming up a stream.
6+ /// Trait to represent types that can be created by multiplying the elements of a stream.
57///
68/// This trait is used to implement the [`product`] method on streams. Types which
79/// implement the trait can be generated by the [`product`] method. Like
@@ -16,8 +18,62 @@ use crate::stream::Stream;
1618pub trait Product < A = Self > : Sized {
1719 /// Method which takes a stream and generates `Self` from the elements by
1820 /// multiplying the items.
19- fn product < S , F > ( stream : S ) -> F
21+ fn product < ' a , S > ( stream : S ) -> Pin < Box < dyn Future < Output = Self > + ' a > >
2022 where
21- S : Stream < Item = A > ,
22- F : Future < Output = Self > ;
23+ S : Stream < Item = A > + ' a ;
24+ }
25+
26+ use core:: ops:: Mul ;
27+ use core:: num:: Wrapping ;
28+ use crate :: stream:: stream:: StreamExt ;
29+
30+ macro_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+ ) ;
2353}
54+
55+ macro_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+
78+ integer_product ! { i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
79+ float_product ! { f32 f64 }
0 commit comments