TypedStash

Struct TypedStash 

Source
pub struct TypedStash<E, W>
where E: Debug + Display + Send + 'static, W: Error + Send + 'static,
{ /* private fields */ }
Expand description

Collects child errors of a specific type, then produces a a wrapper error if any errors were collected.

TypedStash, unlike [BoxedStash], requires all its child errors to have the same type. This allows its output wrapper errors to be strongly typed, avoids heap allocations for boxing, and allows you to to use your own custom wrapper error types by providing a constructor function.

Note that the methods for adding errors to the stash (e.g. TypedStash::push, TypedStash::fail_now, StashableResult::or_stash) take the child error type E directly, whereas the [BoxedStash] methods take Into<BoxedError>.

§Terminal methods

Methods that can return the wrapper error type W (i.e. inside a Result or Option) are considered terminal methods, as they consume the collected errors to produce the wrapper error.

Typically, this doesn’t matter, because these methods are normally called with the ? operator, causing the calling function to return and the stash to likely no longer be used if any errors ocurred. However, if you do call a terminal method without propagating the error immediately (i.e. without using ?), be aware after the call the stash will be empty.

The terminal methods on TypedStash are:

§Generic types

W is the wrapper error type that must implement std::error::Error. E is the child error type that must implement std::fmt::Display and std::fmt::Debug.

Implementations§

Source§

impl<E> TypedStash<E, ErrorList<E>>
where E: Debug + Display + Send + 'static,

Source

pub fn new() -> Self

Creates a new stash that produces an ErrorList with a default summary message if any errors are collected.

The stash will use the default summary message “Encountered N errors:” in any produced ErrorList values, where N is the number of collected errors.

// Create an empty `TypedStash<String, ErrorList<String>>`, with
// the child error type determined via type inference.
let mut stash = TypedStash::new();
assert!(stash.is_empty());
stash.push("some error".to_string());
stash.push("another error".to_string());
assert!(!stash.is_empty());
let error = stash.to_error().unwrap();
assert_eq!(error.summary(), "Encountered 2 errors:");
Source

pub fn with_summary(summary: &'static str) -> Self

Creates a new stash that produces an ErrorList with the provided static summary message if any errors are collected.

If the summary string contains the placeholder {count}, it will be replaced with the number of collected errors when the summary is formatted.

let mut stash = TypedStash::with_summary("Input contains {count} invalid record(s):");
assert!(stash.is_empty());
stash.push("some error".to_string());
assert_eq!(stash.len(), 1);
let error = stash.to_error().unwrap();
assert_eq!(error.summary(), "Input contains 1 invalid record(s):");
Source§

impl<E, W> TypedStash<E, W>
where E: Debug + Display + Send + 'static, W: Error + Send + 'static,

Source

pub fn with_constructor<F>(constructor: F) -> Self
where F: Fn(Vec<E>) -> W + Send + 'static,

Creates a new stash that will use the given constructor to produce the wrapper error if any errors are collected.

The constructor function takes a Vec<E> of the collected child errors and produces a W wrapper error.

§Example
use std::fmt::Debug;
use thiserror::Error;

let product_name = "widget".to_string();
let product_id: u32 = get_product_id(&product_name);

#[derive(Error, Debug)]
#[error("Product errors for {product_name} (ID {product_id}): {errors:?}")]
struct ProductError {
  product_id: u32,
  product_name: String,
  errors: Vec<&'static str>,
}

let mut stash = TypedStash::with_constructor(move |errors| {
  ProductError {
    errors,
    product_id,
    product_name: product_name.clone(),
  }
});

stash.push("Faulty sprockets");
let result = stash.to_error();
let err: ProductError = result.unwrap();

assert_eq!(err.product_id, product_id);
assert_eq!(err.product_name, "widget");
assert_eq!(err.errors, vec!["Faulty sprockets"]);
Source

pub fn push(&mut self, err: E) -> &mut Self

Adds a child error to the stash.

let mut stash = TypedStash::new();

assert_eq!(stash.len(), 0);
stash.push("some error".to_string());
assert_eq!(stash.len(), 1);
Source

pub fn push_all<It>(&mut self, errors: It) -> &mut Self
where It: IntoIterator<Item = E>,

Adds multiple child errors from an iterator to the stash.

let mut stash = TypedStash::new();
assert_eq!(stash.len(), 0);
let errors = vec!["error one".to_string(), "error two".to_string()];
stash.push_all(errors);
assert_eq!(stash.len(), 2);
Source

pub fn check(&mut self, condition: bool, e: E) -> &mut Self

If the condition is false, adds error e to the stash. Otherwise, does nothing.

If you want to return immediately if the condition is false, chain a call to ErrorStash::fail_unless_empty after this method. For example:

let mut stash = BoxedStash::new();
let value = 42;
stash.check(value > 100, "value must be greater than 100")
     .fail_unless_empty()?;
Source

pub fn fail_now(&mut self, e: E) -> Result<(), W>

Adds an error and immediately returns Err(W) with all collected errors.

Trait Implementations§

Source§

impl<E, W> Debug for TypedStash<E, W>
where E: Debug + Display + Send + 'static, W: Error + Send + 'static,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<E> Default for TypedStash<E, ErrorList<E>>
where E: Debug + Display + Send + 'static,

Creates a new TypedStash that emits ErrorList wrapper errors with the default summary message if any errors are collected.

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<E, W> Display for TypedStash<E, W>
where E: Debug + Display + Send + 'static, W: Error + Send + 'static,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<E, W> ErrorStash<E, W> for TypedStash<E, W>
where E: Debug + Display + Send + 'static, W: Error + Send + 'static,

Source§

fn to_error(self) -> Option<W>

If no errors have been collected, returns None. Otherwise, consumes the collected errors and returns Some(W).

Source§

fn to_result<T>(self, closure: impl FnOnce() -> T) -> Result<T, W>

If no errors have been collected, calls the closure and returns Ok(result). Otherwise, consumes the collected errors and returns Err(W).
Source§

fn is_empty(&self) -> bool

Returns true if no errors have been collected. Read more
Source§

fn len(&self) -> usize

Returns the number of collected errors. Read more
Source§

fn ok(&self) -> Option<()>

If no errors have been collected, returns Some(()). Otherwise, returns None. Read more
Source§

fn check_fmt(&mut self, condition: bool, args: Arguments<'_>) -> &mut Self
where E: From<String>,

If the condition is false, adds a formatted error to the stash. Otherwise, does nothing. Read more
Source§

fn fail_unless_empty(&mut self) -> Result<(), W>

If no errors have been collected, returns Ok(()). Otherwise, consumes the collected errors and returns Err(W). Read more
Source§

impl<E, W, T> Extend<T> for TypedStash<E, W>
where E: Display + Debug + Send + 'static, W: Error + Send + 'static, T: Into<E>,

Source§

fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)

Extends a collection with the contents of an iterator. Read more
Source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
Source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
Source§

impl<E, W> From<TypedStash<E, W>> for Option<W>
where E: Debug + Display + Send + 'static, W: Error + Send + 'static,

Source§

fn from(stash: TypedStash<E, W>) -> Self

Converts to this type from the input type.
Source§

impl<E, W> From<TypedStash<E, W>> for Vec<E>
where E: Display + Debug + Send + 'static, W: Error + Send + 'static,

Source§

fn from(stash: TypedStash<E, W>) -> Self

Converts to this type from the input type.
Source§

impl<E, W> IntoIterator for TypedStash<E, W>
where E: Display + Debug + Send + 'static, W: Error + Send + 'static,

Allows consuming the stash to iterate over its collected errors.

This trait allows one stash to be added to another via the TypedStash::push_all method.

Source§

type Item = E

The type of the elements being iterated over.
Source§

type IntoIter = IntoIter<E>

Which kind of iterator are we turning this into?
Source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
Source§

impl<T, W, E> StashableResult<T, E, W, TypedStash<E, W>> for Result<T, E>
where E: Display + Debug + Send + 'static, W: Error + Send + 'static,

Adds the ability to stash errors from a Result whose error type matches the stash’s.

Note that this implementation requires the error types of the stash and the result to match. This differs from the StashableResult implementation for BoxedStash, which leverages the Into<BoxedError> trait to auto-convert compatible error types.

Source§

fn or_stash(self, stash: &mut TypedStash<E, W>) -> Option<T>

Consumes this Result, returning Some(T) if this result is ok, or collecting the error into the provided ErrorStash and returning None if this result is an error. Read more
Source§

fn or_fail(self, stash: &mut TypedStash<E, W>) -> Result<T, W>

Consumes this Result, returning Ok(T) if this result is ok, or collecting the error into the provided ErrorStash and returning the aggregated errors in a Err(W) if this result is an error. Read more
Source§

impl<T, W, E> StashableResult<T, E, W, TypedStash<E, W>> for Result<T, ErrorList<E>>
where E: Display + Debug + Send + 'static, W: Error + Send + 'static,

Adds the ability to stash errors from a Result whose error type is an ErrorList of the stash’s child error type.

The methods of this trait implementation add all the child child errors from this result’s ErrorList to the stash. The ErrorList’s summary message is lost in the process- only the summary from the destination stash, if any, will be used.

The capability is currently only implemented for TypedStash, not BoxedStash,

Source§

fn or_stash(self, stash: &mut TypedStash<E, W>) -> Option<T>

Consumes this Result, returning Some(T) if this result is ok, or collecting the error into the provided ErrorStash and returning None if this result is an error. Read more
Source§

fn or_fail(self, stash: &mut TypedStash<E, W>) -> Result<T, W>

Consumes this Result, returning Ok(T) if this result is ok, or collecting the error into the provided ErrorStash and returning the aggregated errors in a Err(W) if this result is an error. Read more
Source§

impl<T, W, E> StashableResult<T, E, W, TypedStash<E, W>> for Result<T, Vec<E>>
where E: Display + Debug + Send + 'static, W: Error + Send + 'static,

Adds the ability to stash errors from a Result whose error type is a Vec of the stash’s child error type.

The methods of this trait implementation add all the child child errors from this result’s Vec to the stash. The ErrorList’s summary message is lost in the process- only the summary from the destination stash, if any, will be used.

The capability is currently only implemented for TypedStash, not BoxedStash,

Source§

fn or_stash(self, stash: &mut TypedStash<E, W>) -> Option<T>

Consumes this Result, returning Some(T) if this result is ok, or collecting the error into the provided ErrorStash and returning None if this result is an error. Read more
Source§

fn or_fail(self, stash: &mut TypedStash<E, W>) -> Result<T, W>

Consumes this Result, returning Ok(T) if this result is ok, or collecting the error into the provided ErrorStash and returning the aggregated errors in a Err(W) if this result is an error. Read more

Auto Trait Implementations§

§

impl<E, W> Freeze for TypedStash<E, W>

§

impl<E, W> !RefUnwindSafe for TypedStash<E, W>

§

impl<E, W> Send for TypedStash<E, W>

§

impl<E, W> !Sync for TypedStash<E, W>

§

impl<E, W> Unpin for TypedStash<E, W>
where E: Unpin,

§

impl<E, W> !UnwindSafe for TypedStash<E, W>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.