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
use crateFixedPointCoro;
use cratefrom_control_flow;
use cratewith_state;
/// A `Coro` that takes some type as input, and yields the input back until it
/// receives a value that satisfies the predicate `f`, whereupon it returns that
/// value.
///
/// This can be useful as the argument of the `.compose()` operator to implement
/// a "find-first" algorithm, or used with `weave()` to filter a stream of
/// values yielded from another `Coro`.
///
/// # Example 1: find the first element matching a predicate
///
/// ```rust
/// use cocoro::Coro;
/// use cocoro::IntoCoro;
/// use cocoro::until;
///
/// fn find_first<Y, R>(
/// src: impl Coro<(), Y, R>,
/// predicate: impl FnMut(&Y) -> bool,
/// ) -> Option<Y> {
/// src.map_return(|_| None)
/// .compose(until(predicate).map_return(Some))
/// .drive((), |_| ())
/// }
///
/// assert_eq!(Some(10), find_first((1..).into_coro(), |&n| n >= 10))
/// ```
///
/// # Example 2: filter a stream
///
/// ```rust
/// use cocoro::Coro;
/// use cocoro::IntoCoro;
/// use cocoro::Returned;
/// use cocoro::Yielded;
/// use cocoro::until;
/// use cocoro::yield_with;
///
/// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
/// .into_coro()
/// .process(
/// yield_with(|()| {
/// Yielded((), until(|&n| n % 5 == 0).map_yield(|_| ()))
/// }),
/// |r, _| Returned(r),
/// )
/// .assert_yields(5, ())
/// .assert_yields(10, ())
/// .assert_yields(15, ())
/// .assert_returns((), ());
/// ```