1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! Generic abstractions for combining and nesting reduction patterns for iterables.
//!
//! The main entry points to this library are [`Reduce::reduce_with`] and
//! [`Reduce::fold_with`], which can be called on any [`Iterator`], and are
//! similar to [`Iterator::reduce`] and [`Iterator::fold`], respectively,
//! but use a generic implementation of a [`Reductor`] for the reduction logic.
//!
//! The following examples shows some of the basic building blocks from which `reductor`
//! enables building more complex patterns:
//!
//! ```rust
//! use reductor::{Reduce, Sum, Product, Count, Min, Max};
//!
//! let iter = 0..10;
//!
//! let Sum::<u32>(sum) = iter.clone().reduce_with();
//! let Product::<u32>(product) = iter.clone().fold_with(2);
//! let Count(count) = iter.clone().reduce_with();
//! assert_eq!(sum, iter.clone().sum());
//! assert_eq!(product, iter.clone().product::<u32>() * 2);
//! assert_eq!(count, iter.clone().count());
//!
//! let min: Option<Min<u32>> = iter.clone().reduce_with();
//! let Max::<Option<u32>>(max) = iter.clone().reduce_with();
//! assert_eq!(min.unwrap(), Min(iter.start));
//! assert_eq!(max.unwrap(), iter.last().unwrap());
//! ```
//!
//! Notice that unlike [`Sum`] and [`Product`], [`Min`] and [`Max`] won't reduce
//! an empty iterator into the default value. This mirrors the way [`Iterator::max`]
//! returns an [`Option<T>`], unlike [`Iterator::sum`].
//!
//!
//! Now, let's combine two [`Reductor`]s to reduce an iterator that produces a pair of values:
//!
//! ```rust
//! use reductor::{Reduce, Sum, Product};
//!
//! let iter = 0..10;
//!
//! let (Sum::<usize>(sum), Product::<usize>(product)) = iter
//! .clone()
//! .map(|x| (x, x * 2))
//! .reduce_with();
//!
//! assert_eq!(sum, iter.clone().sum());
//! assert_eq!(product, iter.map(|x| x * 2).product());
//! ```
//!
//! Another abstraction provided by this library is [`Reductors`], which allows
//! reducing an iterator producing a single value by a tuple of [`Reductor`]s, in tandem.
//!
//! ```rust
//! use reductor::{Reduce, Reductors, Min, Max, Sum};
//!
//! let iter = 0..10;
//!
//! let Reductors((Min::<usize>(min), Max::<usize>(max))) = iter
//! .clone()
//! .reduce_with::<Option<_>>()
//! .unwrap();
//!
//! assert_eq!(min, iter.start);
//! assert_eq!(max, iter.end - 1);
//!
//! let Reductors((Min::<Option<usize>>(min), Sum::<usize>(sum))) = iter
//! .clone()
//! .reduce_with();
//!
//! assert_eq!(min.unwrap(), iter.start);
//! assert_eq!(sum, iter.sum());
//! ```
//!
//! These constructs allow building very complex iterator loops that compose
//! numerous reductions into a single set of results.
//! ```rust
//! use reductor::{Reduce, Reductors, Count, Sum, Max, Min};
//!
//! let iter = (0_i32..100).filter_map(|x| {
//! if x % 2 == 0 {
//! None
//! } else {
//! Some((x, x.leading_zeros()))
//! }
//! });
//!
//! let Reductors((
//! Count(count),
//! (Sum::<i32>(sum), Reductors((Min::<u32>(min), Max::<u32>(max)))),
//! )) = iter.clone().reduce_with::<Option<_>>().unwrap();
//!
//! assert_eq!(count, iter.clone().count());
//! assert_eq!(sum, iter.clone().map(|(x, ..)| x).sum());
//! assert_eq!(min, iter.clone().map(|(.., x)| x).min().unwrap());
//! assert_eq!(max, iter.map(|(.., x)| x).max().unwrap());
//! ```
pub use ;
pub use Reduce;
pub use *;