zinoma/
async_utils.rs

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
use futures::future::Either;
use futures::StreamExt;
use std::future::Future;

pub async fn both<L, R>(future1: L, future2: R) -> bool
where
    L: Future<Output = bool>,
    R: Future<Output = bool>,
{
    futures::pin_mut!(future1);
    futures::pin_mut!(future2);
    match futures::future::select(future1, future2).await {
        Either::Left((res1, future2)) => res1 && future2.await,
        Either::Right((res2, future1)) => res2 && future1.await,
    }
}

#[cfg(test)]
mod both_tests {
    use super::both;
    use async_std::task;
    use futures::future;

    #[test]
    fn both_are_true() {
        task::block_on(async {
            assert!(both(future::ready(true), future::ready(true)).await)
        })
    }

    #[test]
    fn left_is_false() {
        task::block_on(async {
            assert!(!(both(future::ready(false), future::ready(true)).await))
        })
    }

    #[test]
    fn right_is_false() {
        task::block_on(async {
            assert!(!(both(future::ready(true), future::ready(false)).await))
        })
    }

    #[test]
    fn both_are_false() {
        task::block_on(async {
            assert!(
                !(both(future::ready(false), future::ready(false)).await)
            )
        })
    }
}

/// Resolve as true unless any future in the iterator resolves as false.
pub async fn all<I>(i: I) -> bool
where
    I: IntoIterator,
    I::Item: Future<Output = bool>,
{
    let mut s = futures::stream::iter(i).buffer_unordered(64);
    while let Some(r) = s.next().await {
        if !r {
            return false;
        }
    }

    true
}

#[cfg(test)]
mod all_tests {
    use super::all;
    use async_std::task;
    use future::Ready;
    use futures::future;

    #[test]
    fn true_for_empty() {
        task::block_on(async {
            let futures = Vec::<Ready<bool>>::new();
            assert!(all(futures).await);
        })
    }

    #[test]
    fn true_if_all_true() {
        task::block_on(async {
            let futures = vec![future::ready(true), future::ready(true)];
            assert!(all(futures).await);
        })
    }

    #[test]
    fn false_if_any_false() {
        task::block_on(async {
            assert!(
                !(all(vec![future::ready(false), future::ready(true)]).await)
            );
            assert!(
                !(all(vec![future::ready(true), future::ready(false)]).await)
            );
        })
    }
}