effect-rs 0.1.0

A high-performance, strictly-typed, functional effect system for Rust.
Documentation
use effect_rs::{Effect, Exit, Ref, Runtime, Schedule};

#[test]
fn test_retry_recurs() {
    let rt = Runtime::new();
    let counter = Ref::new(0);

    let program = counter
        .update(|x| x + 1)
        .map_error(|_| "update error")
        .flat_map(|val| {
            if val < 4 {
                Effect::fail("error")
            } else {
                Effect::succeed(val)
            }
        })
        .retry(Schedule::<&str, usize>::recurs(5));

    let result = rt.block_on(program, ());
    match result {
        Exit::Success(val) => assert_eq!(val, 4), // Fails 3 times (1,2,3), Succeeds on 4th
        Exit::Failure(_) => panic!("Expected success"),
    }
}

#[test]
fn test_retry_fail() {
    let rt = Runtime::new();
    let counter = Ref::new(0);

    // Fails always. Recurs 3 times. Should return failure.
    let program = counter
        .update(|x| x + 1)
        .map_error(|_| "update failed")
        .flat_map(|_| Effect::<(), &str, ()>::fail("always error"))
        .retry(Schedule::<&str, usize>::recurs(3));

    let result = rt.block_on(program, ());
    match result {
        Exit::Success(_) => panic!("Expected failure"),
        Exit::Failure(_cause) => {
            // Should fail after 3 retries (4 attempts total)
            // But retry only returns the last error.
            let count_check = rt.block_on(counter.get(), ());
            match count_check {
                Exit::Success(c) => assert_eq!(c, 4), // Initial + 3 retries
                _ => panic!("Expected count"),
            }
        }
    }
}