1.4 KiB
1.4 KiB
Style Guide for all of Luminescent Dreams projects
Many projects predate this style guide. Future work should follow this style guide. Previous work should be updated on an opportunistic basis.
Prefer let/else bindings over match
If the point of a match statement is to unwrap a value or exit early, prefer let/else bindings to a match statement:
Avoid:
let game = match db.game(&image.game)? {
Some(game) => game,
None => return Ok(Err(Error::NotFound(image.game.as_str().to_string()))),
};
Prefer:
let Some(game) = db.game(&image.game)? else {
return Ok(Err(Error::NotFound(image.game.as_str().to_string())));
};
Use nested results to separate safe failures from critical failures
Error Handling in a Correctness-Critical Rust Project | sled-rs.github.io
If a function could return a combination of ordinary errors and fatal errors, separate those into separate error types and nest them.
Avoid:
fn fallible() -> Result<(), BlobError>
Prefer:
fn fallible() -> Result<Result<(), Error>, Fatal>
fn search() -> Result<Option<()>, Fatal>
fn fatal_only() -> Result<(), Fatal>
Ordinary errors should never be blanket-promoted to fatal errors, and fatal errors should never be caught except at the top level of the application. Functions receiving a fatal error MAY choose to perform cleanup before propogating the error further.