Fallible might not look like a clear win ATM due to the additional .into() calls, but I think this will change when error propagation is used more systematically. For example,
match fs::read_to_string(file_name) {
Ok(config) => match toml::from_str(&config) {
Ok(config) => config,
Err(error) => {
return Err(format!(
"ERROR: Could not parse config file \"{}\": {}",
file_name, error
)
.into());
}
},
Err(error) => {
return Err(format!(
"ERROR: Could not read config file \"{}\": {}",
file_name, error
)
.into());
}
}
could be done as
fn read_config(path: &Path) -> Fallible<AnyConfig> {
let buf = fs::read_to_string(path)?;
let val = toml::from_str(&buf)?;
Ok(val)
}
...
let config = read_config(path).map_err(|err| format!("ERROR: Could not read config file \"{}\": {}", path.display(), err))?
which depends on usign Box<dyn Error> to unify std::io::Error and toml::de::Error, but I did not want to mix to many changes into one PR. (I am also not I understand what the occurrences_of == 0 check above that snippet actually does.)
Fallible
might not look like a clear win ATM due to the additional.into()
calls, but I think this will change when error propagation is used more systematically. For example,could be done as
which depends on usign
Box<dyn Error>
to unifystd::io::Error
andtoml::de::Error
, but I did not want to mix to many changes into one PR. (I am also not I understand what theoccurrences_of == 0
check above that snippet actually does.)