gust-stdlib 0.2.0

Standard library of reusable Gust state machines (circuit breaker, retry, saga, rate limiter, and more)
Documentation
machine Saga<S> {
    state Planning(steps: Vec<S>)
    state Executing(steps: Vec<S>, index: i64, completed: Vec<S>)
    state Compensating(completed: Vec<S>, index: i64, reason: String)
    state Committed(completed: Vec<S>)
    state Aborted(reason: String, compensated_count: i64)

    transition begin: Planning -> Executing
    transition execute_next: Executing -> Executing | Compensating | Committed
    transition compensate_next: Compensating -> Compensating | Aborted

    async effect execute_forward(step: S) -> Result<S, String>
    async effect execute_compensate(step: S) -> Result<i64, String>
    effect len(steps: Vec<S>) -> i64
    effect get_step(steps: Vec<S>, index: i64) -> S
    effect push_step(steps: Vec<S>, step: S) -> Vec<S>
    effect empty_steps() -> Vec<S>

    on begin() {
        goto Executing(steps, 0, perform empty_steps());
    }

    async on execute_next() {
        if index >= perform len(steps) {
            goto Committed(completed);
        }

        let current = perform get_step(steps, index);
        let result = perform execute_forward(current);
        match result {
            Ok(done) => {
                let next_completed = perform push_step(completed, done);
                goto Executing(steps, index + 1, next_completed);
            }
            Err(err) => {
                goto Compensating(completed, perform len(completed) - 1, err);
            }
        }
    }

    async on compensate_next() {
        if index < 0 {
            goto Aborted(reason, perform len(completed));
        }

        let current = perform get_step(completed, index);
        let result = perform execute_compensate(current);
        match result {
            Ok(_) => {
                goto Compensating(completed, index - 1, reason);
            }
            Err(err) => {
                goto Aborted(err, perform len(completed) - index);
            }
        }
    }
}