tailcall 2.0.1

Stack-safe tail calls on stable Rust
Documentation
use tailcall::trampoline;

#[test]
fn is_even_redux() {
    assert!(is_even(1000));
    assert!(!is_even(1001));
}

#[test]
fn is_odd_redux() {
    assert!(!is_odd(1000));
    assert!(is_odd(1001));
}

#[test]
fn sums_csv_numbers_with_mutual_recursion() {
    assert_eq!(sum_csv_numbers("10, 20,3"), 33);
    assert_eq!(sum_csv_numbers("7  , 8,   9"), 24);
    assert_eq!(sum_csv_numbers(""), 0);
}

fn is_even(x: u128) -> bool {
    trampoline::run(build_is_even_action(x))
}

#[doc(hidden)]
#[inline(always)]
fn build_is_even_action(x: u128) -> trampoline::Action<'static, bool> {
    trampoline::call(move || {
        if x > 0 {
            build_is_odd_action(x - 1)
        } else {
            trampoline::done(true)
        }
    })
}

fn is_odd(x: u128) -> bool {
    trampoline::run(build_is_odd_action(x))
}

#[doc(hidden)]
#[inline(always)]
fn build_is_odd_action(x: u128) -> trampoline::Action<'static, bool> {
    trampoline::call(move || {
        if x > 0 {
            build_is_even_action(x - 1)
        } else {
            trampoline::done(false)
        }
    })
}

fn sum_csv_numbers(input: &str) -> u64 {
    trampoline::run(build_skip_separators_action(input.as_bytes(), 0))
}

#[doc(hidden)]
#[inline(always)]
fn build_skip_separators_action<'a>(rest: &'a [u8], total: u64) -> trampoline::Action<'a, u64> {
    trampoline::call(move || match rest {
        [b' ' | b',', tail @ ..] => build_skip_separators_action(tail, total),
        [] => trampoline::done(total),
        _ => build_read_number_action(rest, total, 0),
    })
}

#[doc(hidden)]
#[inline(always)]
fn build_read_number_action<'a>(
    rest: &'a [u8],
    total: u64,
    current: u64,
) -> trampoline::Action<'a, u64> {
    trampoline::call(move || match rest {
        [digit @ b'0'..=b'9', tail @ ..] => {
            let current = current * 10 + u64::from(digit - b'0');
            build_read_number_action(tail, total, current)
        }
        _ => build_skip_separators_action(rest, total + current),
    })
}