Similarly to Result::inspect_err() it could be worth having Option::on_none.
This can be especially useful for logging in chained expressions:
pub fn load() -> Option<Self> {
Self::file_path()
.or_else(|| {
warn!("User configuration directory not found.");
None
})
.and_then(|filename| {
File::open(&filename)
.inspect_err(|error| {
if error.kind() != ErrorKind::NotFound {
error!("Could not read user configuration file: {error}");
}
})
.ok()
.and_then(|file| {
read_to_string(file)
.inspect_err(|error| {
error!("Could not read user configuration file: {error}");
})
.ok()
.and_then(|text| {
serde_json::from_str(&text)
.inspect_err(|error| {
error!("Malformed user configuration file: {error}");
})
.ok()
})
})
})
}
It would be a bit more ergonomic, to not having to return the None:
pub fn load() -> Option<Self> {
Self::file_path()
.on_none(|| warn!("User configuration directory not found."))
.and_then(|filename| {
File::open(&filename)
.inspect_err(|error| {
if error.kind() != ErrorKind::NotFound {
error!("Could not read user configuration file: {error}");
}
})
.ok()
.and_then(|file| {
read_to_string(file)
.inspect_err(|error| {
error!("Could not read user configuration file: {error}");
})
.ok()
.and_then(|text| {
serde_json::from_str(&text)
.inspect_err(|error| {
error!("Malformed user configuration file: {error}");
})
.ok()
})
})
})
}