recursion/
recursion.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
use par::{
    exchange::{Recv, Send},
    queue::Dequeue,
    runtimes::tokio::fork,
    Dual,
};

enum Counting {
    More(Recv<i64, Recv<Counting>>),
    Done(Send<i64>),
}

fn start_counting() -> Send<Counting> {
    fork(|mut numbers: Recv<Counting>| async {
        let mut total = 0;
        loop {
            match numbers.recv1().await {
                Counting::More(number) => {
                    let (n, next) = number.recv().await;
                    total += n;
                    numbers = next;
                }
                Counting::Done(report) => break report.send1(total),
            }
        }
    })
}

type Numbers = Dequeue<i64, Send<i64>>;
type Counter = Dual<Numbers>;

fn start_counting_with_queue() -> Counter {
    fork(|numbers: Numbers| async {
        let (total, report) = numbers
            .fold(0, |total, add| async move { total + add })
            .await;
        report.send1(total);
    })
}

#[tokio::main]
async fn main() {
    let sum = start_counting()
        .choose(Counting::More)
        .send(1)
        .choose(Counting::More)
        .send(2)
        .choose(Counting::More)
        .send(3)
        .choose(Counting::More)
        .send(4)
        .choose(Counting::More)
        .send(5)
        .choose(Counting::Done)
        .recv1()
        .await;

    assert_eq!(sum, 15);

    let sum = start_counting_with_queue()
        .push(1)
        .push(2)
        .push(3)
        .push(4)
        .push(5)
        .close()
        .recv1()
        .await;

    assert_eq!(sum, 15);
}