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
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)
}
}