corophage 0.4.1

Algebraic effects for stable Rust
Documentation
use std::marker::PhantomData;

use corophage::coroutine::Co;
use corophage::prelude::*;

pub struct Cancel;

impl Effect for Cancel {
    type Resume<'r> = Never;

    fn shorten_resume<'a: 'b, 'b>(resume: Never) -> Never {
        match resume {}
    }
}

pub struct Log<'a>(pub &'a str);

impl<'a> Effect for Log<'a> {
    type Resume<'r> = ();

    fn shorten_resume<'a_: 'b, 'b>(resume: ()) {
        resume
    }
}

pub struct FileRead(pub String);

impl Effect for FileRead {
    type Resume<'r> = String;

    fn shorten_resume<'a: 'b, 'b>(resume: String) -> String {
        resume
    }
}

#[derive(Default)]
pub struct GetState<S> {
    _marker: PhantomData<S>,
}

impl<S> Effect for GetState<S>
where
    S: Sync + Send,
{
    type Resume<'r> = S;

    fn shorten_resume<'a: 'b, 'b>(resume: S) -> S {
        resume
    }
}

pub struct SetState<S>(pub S);

impl<S> Effect for SetState<S> {
    type Resume<'r> = ();

    fn shorten_resume<'a: 'b, 'b>(resume: ()) {
        resume
    }
}

pub type CoEffs = Effects![Cancel, Log<'static>, FileRead, GetState<u64>, SetState<u64>];

pub fn co() -> Co<'static, CoEffs, ()> {
    Co::new(|yielder| async move {
        println!("Logging...");
        let () = yielder.yield_(Log("Hello, world!")).await;

        println!("Reading file...");
        let text = yielder.yield_(FileRead("example.txt".to_string())).await;
        println!("Read file: {text}");

        let state = yielder.yield_(GetState::default()).await;
        println!("State: {state}");
        yielder.yield_(SetState(state * 2)).await;
        let state = yielder.yield_(GetState::default()).await;
        println!("State: {state}");

        println!("Cancelling...");
        yielder.yield_(Cancel).await;
        println!("Cancelled!");
    })
}