Is there any way to express the following code in a more concise manner? The function should only continue if the result is Ok()
, else it should return a default object. The code I came up with looks kind of unidiomatic, so I wondered if there is a better and more concise way.
fn get_config() -> Config {
let cfg = match get_config_file_path() { // can return a (custom) PathError
Ok(c) => c,
Err(e) => {
error(&*format!(
"{} -> Using default configuration",
e.description
));
return Config::default();
}
};
let cfg_str = match fs::read_to_string(&cfg) { // io::Error
Ok(c) => c,
Err(_) => {
error("Failed to read config file");
return Config::default();
}
};
toml::from_str(&*cfg_str).unwrap_or_else(|_| { // toml::de::Error
error("Failed to parse config file");
Config::default()
})
}
Edit: My solution:
I created the following macro:
macro_rules! unwrap_or_return {
( $e:expr, $c:expr) => {
match $e {
Ok(x) => x,
Err(_) => return $c,
}
};
}
fn get_config() -> Config {
let cfg = unwrap_or_return!(get_config_file_path(), {
error("Failed to get path to configuration file");
Config::default()
});
let cfg_str = unwrap_or_return!(fs::read_to_string(&cfg), {
error("Failed to read config file");
Config::default()
});
toml::from_str(&*cfg_str).unwrap_or_else(|_| {
error("Failed to parse config file");
Config::default()
})
}