Skip to content

An experiment in an augmented error handling type for Rust

License

Notifications You must be signed in to change notification settings

bruxisma/outcome

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Overview

Audit Pull Request codecov Documentation

Outcome<S, M, F> is an augmentation of the Result type found in the Rust standard library.

It is an enum with the variants

  • Success(S), representing success and containing a value
  • Mistake(M), representing an optionally retryable error and containing a value
  • Failure(F), representing failure and containing a value.
enum Outcome<S, M, F> {
  Success(S),
  Mistake(M),
  Failure(F),
}

Outcome is an augmentation to Result. It adds a third state to the "success or failure" dichotomy that Result<T, E> models. This third state is that of a soft or retryable error. A retryable error is one where an operation might not have succeeded, either due to other operations (e.g., a disk read or write not completing), misconfiguration (e.g., forgetting to set a specific flag before calling a function), or busy resources (e.g., attempting to lock an audio, video, or database resource).

use outcome::prelude::*;

#[derive(Debug, PartialEq)]
enum Version { V1, V2 }

#[derive(Debug, PartialEq)]
struct EmptyInput;

fn parse_version(header: &[u8]) -> Outcome<Version, EmptyInput, &'static str> {
  match header.get(0) {
    None => Mistake(EmptyInput),
    Some(&1) => Success(Version::V1),
    Some(&2) => Success(Version::V2),
    Some(_) => Failure("invalid or unknown version"),
  }
}

let version = parse_version(&[]);
assert_eq!(version, Mistake(EmptyInput));

Usage

At this time, the name outcome is already taken on crates.io. As crates.io does not yet support namespaces or collections, we've had to take a unique approach to still publish the crate. To do this, we've generated a UUIDv5 string via python:

from uuid import *
print(uuid5(uuid5(NAMESPACE_DNS, "occult.work"), "outcome"))

This should generate the string 46f94afc-026f-5511-9d7e-7d1fd495fb5c. Thus the dependency in your Cargo.toml will look something like:

[dependencies]
outcome-46f94afc-026f-5511-9d7e-7d1fd495fb5c = "*"

However, the exported library is still named outcome, so importing it is treated the same:

use outcome::prelude::*;

Users can also work around this by using the package key in their dependency declaration:

[dependencies.outcome]
version = "*"
package = "outcome-46f94afc-026f-5511-9d7e-7d1fd495fb5c"

Is this solution friendly to users? No, but neither is the lack of namespacing nor a squatting policy on crates.io. If/when this problem is resolved, this crate's documentation (and name!) will be changed and all versions will be yanked.

About

An experiment in an augmented error handling type for Rust

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Contributors 4

  •  
  •  
  •  
  •