pub trait AttemptFrom<T>: Sized {
    type Mistake;
    type Failure;

    fn attempt_from(value: T) -> Outcome<Self, Self::Mistake, Self::Failure>;
}
Expand description

Outcome’s analogue to TryFrom, and the reciprocal of TryInto.

This is useful when doing a type conversion that might trivially succeed, but also might need special error handling. AttemptFrom adds the additional ability to inform the caller that they are free to retry the conversion event. This is extremely useful in cases where non-Copyable types are consumed during the conversion, but users

  1. Cannot control the error type returned to give useful diagnostics, either to a caller further up the chain OR to logging information
  2. May want to try a different conversion operation instead (e.g., trying to treat a string as a filepath without having to convert it to the underlying native storage format first)

Examples

use outcome::convert::*;
use outcome::prelude::*;

#[derive(Debug, PartialOrd, PartialEq, Ord, Eq, Hash)]
enum Version { V1, V2 }

#[derive(Debug, PartialOrd, PartialEq, Ord, Eq, Hash)]
struct EmptyInput;

#[derive(Debug, PartialOrd, PartialEq, Ord, Eq, Hash)]
enum ParseError {
  InvalidVersion(u8),
}

impl std::fmt::Display for ParseError {
  fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    match self {
      Self::InvalidVersion(v) => write!(f, "Expected a valid version, received: {:x?}", v)
    }
  }
}

impl<const N: usize> AttemptFrom<&[u8; N]> for Version {
  type Mistake = EmptyInput;
  type Failure = ParseError;

  fn attempt_from (value: &[u8; N]) -> Outcome<Self, Self::Mistake, Self::Failure> {
    match value.get(0) {
      None => Mistake(EmptyInput),
      Some(&1) => Success(Version::V1),
      Some(&2) => Success(Version::V2),
      Some(&value) => Failure(ParseError::InvalidVersion(value)),
    }
  }
}

let empty = Version::attempt_from(&[]);
let v1 = Version::attempt_from(&[1u8]);
let v2 = Version::attempt_from(&[2u8]);
let v3 = Version::attempt_from(&[3u8]);
assert_eq!(empty, Mistake(EmptyInput));
assert_eq!(v1, Success(Version::V1));
assert_eq!(v2, Success(Version::V2));
assert_eq!(v3, Failure(ParseError::InvalidVersion(3)));

Required Associated Types

The retryable error type

The failure error type

Required Methods

Performs the conversion

Implementors