oxihuman-core 0.1.2

Core data structures, algorithms, and asset management for OxiHuman
Documentation
#![allow(dead_code)]

#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ChainError {
    message: String,
}

#[allow(dead_code)]
#[derive(Debug, Clone)]
pub enum ResultChain<T> {
    Ok(T),
    Err(ChainError),
}

#[allow(dead_code)]
pub fn new_result_chain<T>(val: T) -> ResultChain<T> {
    ResultChain::Ok(val)
}

#[allow(dead_code)]
pub fn chain_ok<T>(val: T) -> ResultChain<T> {
    ResultChain::Ok(val)
}

#[allow(dead_code)]
pub fn chain_err<T>(msg: &str) -> ResultChain<T> {
    ResultChain::Err(ChainError {
        message: msg.to_string(),
    })
}

#[allow(dead_code)]
pub fn chain_map<T, U, F: FnOnce(T) -> U>(rc: ResultChain<T>, f: F) -> ResultChain<U> {
    match rc {
        ResultChain::Ok(v) => ResultChain::Ok(f(v)),
        ResultChain::Err(e) => ResultChain::Err(e),
    }
}

#[allow(dead_code)]
pub fn chain_and_then<T, U, F: FnOnce(T) -> ResultChain<U>>(
    rc: ResultChain<T>,
    f: F,
) -> ResultChain<U> {
    match rc {
        ResultChain::Ok(v) => f(v),
        ResultChain::Err(e) => ResultChain::Err(e),
    }
}

#[allow(dead_code)]
pub fn chain_unwrap_or<T>(rc: ResultChain<T>, default: T) -> T {
    match rc {
        ResultChain::Ok(v) => v,
        ResultChain::Err(_) => default,
    }
}

#[allow(dead_code)]
pub fn chain_is_ok<T>(rc: &ResultChain<T>) -> bool {
    matches!(rc, ResultChain::Ok(_))
}

#[allow(dead_code)]
pub fn chain_error_message<T>(rc: &ResultChain<T>) -> Option<&str> {
    match rc {
        ResultChain::Err(e) => Some(&e.message),
        ResultChain::Ok(_) => None,
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ok() {
        let r = chain_ok::<i32>(42);
        assert!(chain_is_ok(&r));
    }

    #[test]
    fn test_err() {
        let r: ResultChain<i32> = chain_err("fail");
        assert!(!chain_is_ok(&r));
    }

    #[test]
    fn test_error_message() {
        let r: ResultChain<i32> = chain_err("oops");
        assert_eq!(chain_error_message(&r), Some("oops"));
    }

    #[test]
    fn test_ok_no_error() {
        let r = chain_ok(1);
        assert_eq!(chain_error_message(&r), None);
    }

    #[test]
    fn test_map() {
        let r = chain_ok(10);
        let r2 = chain_map(r, |x| x * 2);
        assert_eq!(chain_unwrap_or(r2, 0), 20);
    }

    #[test]
    fn test_map_err() {
        let r: ResultChain<i32> = chain_err("bad");
        let r2 = chain_map(r, |x| x * 2);
        assert!(!chain_is_ok(&r2));
    }

    #[test]
    fn test_and_then() {
        let r = chain_ok(5);
        let r2 = chain_and_then(r, |x| chain_ok(x + 1));
        assert_eq!(chain_unwrap_or(r2, 0), 6);
    }

    #[test]
    fn test_and_then_err() {
        let r = chain_ok(5);
        let r2 = chain_and_then(r, |_| chain_err::<i32>("nope"));
        assert!(!chain_is_ok(&r2));
    }

    #[test]
    fn test_unwrap_or_default() {
        let r: ResultChain<i32> = chain_err("err");
        assert_eq!(chain_unwrap_or(r, 99), 99);
    }

    #[test]
    fn test_new_result_chain() {
        let r = new_result_chain(7);
        assert!(chain_is_ok(&r));
        assert_eq!(chain_unwrap_or(r, 0), 7);
    }
}