product.rs - source (original) (raw)

async_std/stream/

product.rs

1use core::pin::Pin;
2use core::future::Future;
3
4use crate::stream::Stream;
5
6/// Trait to represent types that can be created by multiplying the elements of a stream.
7///
8/// This trait is used to implement the [`product`] method on streams. Types which
9/// implement the trait can be generated by the [`product`] method. Like
10/// [`FromStream`] this trait should rarely be called directly and instead
11/// interacted with through [`Stream::product`].
12///
13/// [`product`]: trait.Product.html#tymethod.product
14/// [`FromStream`]: trait.FromStream.html
15/// [`Stream::product`]: trait.Stream.html#method.product
16#[cfg(feature = "unstable")]
17#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
18pub trait Product<A = Self>: Sized {
19    /// Method which takes a stream and generates `Self` from the elements by
20    /// multiplying the items.
21    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! num_product {
31    ($one:expr, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span></span></span></span>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 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>&gt;</mo><mi>f</mi><mi>o</mi><mi>r</mi></mrow><annotation encoding="application/x-tex">a&gt; for </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.5782em;vertical-align:-0.0391em;"></span><span class="mord mathnormal">a</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&gt;</span><span class="mspace" style="margin-right:0.2778em;"></span></span><span class="base"><span class="strut" style="height:0.8889em;vertical-align:-0.1944em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal" style="margin-right:0.02778em;">or</span></span></span></span>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}
50
51macro_rules! integer_product {
52    ($($a:ty)*) => (
53        num_product!(1, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span></span></span></span>a)*);
54        num_product!(Wrapping(1), <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>W</mi><mi>r</mi><mi>a</mi><mi>p</mi><mi>p</mi><mi>i</mi><mi>n</mi><mi>g</mi><mo>&lt;</mo></mrow><annotation encoding="application/x-tex">(Wrapping&lt;</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal" style="margin-right:0.13889em;">W</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">a</span><span class="mord mathnormal">pp</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">&lt;</span></span></span></span>a>)*);
55    );
56}
57
58macro_rules! float_product {
59    ($($a:ty)*) => (
60        num_product!(1.0, <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo></mrow><annotation encoding="application/x-tex">(</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span></span></span></span>a)*);
61    );
62}
63
64integer_product!{ i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize }
65float_product!{ f32 f64 }