Function bicoro::receive

source ·
pub fn receive<'a, I, O>() -> Coroutine<'a, I, O, I>
Expand description

Suspend this coroutine until an input arrives

The result can be bound. Eg. the below reads a int and converts it into a string

use bicoro::*;
let co :Coroutine<i32,(),i32> = receive();
Examples found in repository?
examples/fsm-input-driven.rs (line 32)
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
pub fn needs_input() -> Coroutine<'static, Input, Output, turnstile::Input> {
    // this is a recursive function. Any easy way to express a loop
    fn loop_(input: Input) -> Coroutine<'static, Input, Output, turnstile::Input> {
        match input.0.trim() {
            "push" => result(turnstile::Input::Push),
            "coin" => result(turnstile::Input::Coin),
            other => {
                let error = format!("Turnstile: 'I don't understand {}' \r\n", other);
                let prompt = "What do you try instead?".to_string();

                send(Output::StdErr(error))
                    .and_then(|()| send(Output::StdOut(prompt)))
                    .and_then(|()| send(Output::Flush))
                    .and_then(|()| receive())
                    .and_then(loop_) // we loop if it's invalid, we need to get that input for the turnstile!
            }
        }
    }
    // kicks off the loop
    let initial_prompt = format!("What do you do?: ");
    send(Output::StdOut(initial_prompt))
        .and_then(|()| send(Output::Flush))
        .and_then(|()| receive())
        .and_then(loop_)
}
More examples
Hide additional examples
examples/turnstile/mod.rs (line 58)
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
pub fn create<'a>() -> Coroutine<'a, Input, Output, Never> {
    // recursive function. that takes the current state, input and
    // gives a co-routine.
    fn on_input<'a>(state: State, input: Input) -> Coroutine<'a, Input, Output, Never> {
        // coroutine section that sends the output, and sets the next state
        let next = match (state, input) {
            (State::Locked, Input::Coin) => m! {
                send(Output::Unlocked);
                result(State::Unlocked)
            },
            (State::Locked, Input::Push) => m! {
                send(Output::NoChange);
                result(State::Locked)
            },
            (State::Unlocked, Input::Coin) => m! {
                send(Output::NoChange);
                result(State::Unlocked)
            },
            (State::Unlocked, Input::Push) => m! {
                send(Output::Locked);
                result(State::Locked)
            },
        };

        // read an input, and call on_input again
        m! {
            state <- next;
            input <- receive();
            on_input(state, input)
        }
    }
    let initial_state = State::Locked;
    m! {
        input <- receive();
        on_input(initial_state, input)
    }
}