recursion/
recursion.rs

1use par::{
2    exchange::{Recv, Send},
3    queue::Dequeue,
4    runtimes::tokio::fork,
5    Dual,
6};
7
8enum Counting {
9    More(Recv<i64, Recv<Counting>>),
10    Done(Send<i64>),
11}
12
13fn start_counting() -> Send<Counting> {
14    fork(|mut numbers: Recv<Counting>| async {
15        let mut total = 0;
16        loop {
17            match numbers.recv1().await {
18                Counting::More(number) => {
19                    let (n, next) = number.recv().await;
20                    total += n;
21                    numbers = next;
22                }
23                Counting::Done(report) => break report.send1(total),
24            }
25        }
26    })
27}
28
29type Numbers = Dequeue<i64, Send<i64>>;
30type Counter = Dual<Numbers>;
31
32fn start_counting_with_queue() -> Counter {
33    fork(|numbers: Numbers| async {
34        let (total, report) = numbers
35            .fold(0, |total, add| async move { total + add })
36            .await;
37        report.send1(total);
38    })
39}
40
41#[tokio::main]
42async fn main() {
43    let sum = start_counting()
44        .choose(Counting::More)
45        .send(1)
46        .choose(Counting::More)
47        .send(2)
48        .choose(Counting::More)
49        .send(3)
50        .choose(Counting::More)
51        .send(4)
52        .choose(Counting::More)
53        .send(5)
54        .choose(Counting::Done)
55        .recv1()
56        .await;
57
58    assert_eq!(sum, 15);
59
60    let sum = start_counting_with_queue()
61        .push(1)
62        .push(2)
63        .push(3)
64        .push(4)
65        .push(5)
66        .close()
67        .recv1()
68        .await;
69
70    assert_eq!(sum, 15);
71}