Hello there.
I'm working on a rust project. which requires lot's of code to load a backup value when current value is None. Is there a elegant way to implement this without a helper trait?
use anyhow::anyhow;
use std::error::Error;
pub trait OptionUtil<T> {
fn ok_or_else_result<E>(self, f: impl FnOnce() -> Result<T, E>) -> Result<T, E>;
}
impl<T> OptionUtil<T> for Option<T> {
fn ok_or_else_result<E>(self, f: impl FnOnce() -> Result<T, E>) -> Result<T, E> {
match self {
Some(v) => Ok(v),
None => f(),
}
}
}
fn main() -> Result<(), Box<dyn Error>> {
let config1: Option<i32> = None;
// my current solution
let config1_final = config1.ok_or_else_result(load_backup_value)?;
println!("hello {}", &config1_final);
// this works but can not avoid call `load_backup_value`
// when config1 is Some
let config1_final = config1.unwrap_or(load_backup_value()?);
println!("hello {}", &config1_final);
// this works but a useless Error created
let config1_final = config1
.ok_or(anyhow!("some dummy error"))
.or_else(|_| load_backup_value())?;
println!("hello {}", &config1_final);
Ok(())
}
fn load_backup_value() -> Result<i32, Box<dyn Error>> {
Ok(42) // some code might return Err
}
Output:
hello 42
hello 42
hello 42