rust

Transform a Result type to another based on the Ok value


How can I idiomatically transform a Result type to another Result type based on the Ok value?

fn get_res1() -> Result<bool, ()> {
    Ok(true)
}

fn get_res2() -> Result<(), String> {
    let res = get_res1().map_err(|err| String::from("Execution failed"))?;

    // map Ok value to Result type(function return type) based on its value
    // Is it possible to combine the below transformation with the above Result type method map_err?
    if !res {
        return Err(String::from("Operation failed"));
    }

    Ok(())
}

Solution

  • I think there are basically three ways, which all do the same thing and are just stylistically different.

    fn get_res2_1() -> Result<(), String> {
        let res = get_res1();
    
        match res {
            Ok(true) => Ok(()),
            Ok(false) => Err(String::from("Operation failed")),
            Err(_) => Err(String::from("Execution failed")),
        }
    }
    
    fn get_res2_2() -> Result<(), String> {
        let res = get_res1();
    
        match res {
            Ok(b) if !b => Err(String::from("Operation failed")),
            Ok(_) => Ok(()),
            Err(_) => Err(String::from("Execution failed")),
        }
    }
    
    fn get_res2_3() -> Result<(), String> {
        let res = get_res1();
    
        res.map_err(|_| String::from("Execution failed"))
            .and_then(|b| {
                if b {
                    Ok(())
                } else {
                    Err(String::from("Operation failed"))
                }
            })
    }