Been experimenting with coroutines in Rust. I wish there was some syntactic sugar when calling a coroutine inside another coroutine to automatically yield, like how the ? operator automatically returns None/Err. I'm using a little macro_rule to clean it up since I'm doing it so much.
"""
fn parse_data_state(
token_buffer: TokenBuffer,
) -> impl Coroutine<(), Yield = (), Return = Result<Option<token::Token>, error::TokenizerError>> {
#[coroutine]
move || {
match run_to_completion!(xml_decl::parse_xml_decl(token_buffer.clone())) {
Ok(Some(token)) => return Ok(Some(token)),
_ => (),
};
...
}
"""
"""
#[macro_export]
macro_rules! run_to_completion {
($coro:expr) => {{
let complete;
loop {
match core::ops::Coroutine::resume(Pin::new(&mut $coro), ()) {
core::ops::CoroutineState::Yielded(y) => yield y,
core::ops::CoroutineState::Complete(result) => {
complete = result;
break;
}
}
}
complete
}};
}
"""