pub trait TryMapOrStash<T, E, S, I, const N: usize>where
E: Into<I>,{
// Required method
fn try_map_or_stash<F, U>(
self,
f: F,
stash: &mut S,
) -> StashedResult<'_, [U; N], I>
where F: FnMut(T) -> Result<U, E>;
}Expand description
Adds the try_map_or_stash method on
[T; _] and
[Result<T, E>; _]
if E implements Into<I>.
Do not implement this trait.
Importing the trait is sufficient due to blanket implementations.
The trait is implemented automatically if E implements Into<I>,
where I is the inner error type,
typically prelude::Stashable.
Required Methods§
Sourcefn try_map_or_stash<F, U>(
self,
f: F,
stash: &mut S,
) -> StashedResult<'_, [U; N], I>
fn try_map_or_stash<F, U>( self, f: F, stash: &mut S, ) -> StashedResult<'_, [U; N], I>
Counterpart to array::try_map from the Rust standard library
that will not short-circuit,
but instead move all Err elements/results into an error stash.
This method will touch all elements of arrays
of type [T; _] or [Result<T, E>; _],
mapping each T or Ok(T) via the supplied mapping function.
Each time a Result::Err element is encountered
or an element is mapped to a Result::Err value,
that error will be put into the supplied error stash.
If there are one or more Result::Errs,
this method will return a StashedResult::Err
wrapping that error stash.
Otherwise, this method will return a StashedResult::Ok
containing an array of the mapped elements, in order.
Here’s an example using [T; _]:
#[cfg(any(feature = "rust-v1.81", feature = "std"))]
use lazy_errors::{prelude::*, Result};
#[cfg(not(any(feature = "rust-v1.81", feature = "std")))]
use lazy_errors::surrogate_error_trait::{prelude::*, Result};
fn parse_each_u8(input: [&str; 2]) -> Result<[u8; 2]> {
let mut errs = ErrorStash::new(|| "Invalid input");
let numbers = input.try_map_or_stash(u8::from_str, &mut errs);
let numbers: [u8; 2] = try2!(numbers);
Ok(numbers)
}
let numbers = parse_each_u8(["42", "0"]).unwrap();
let errors_1 = parse_each_u8(["X", "0"]).unwrap_err();
let errors_2 = parse_each_u8(["X", "Y"]).unwrap_err();
assert_eq!(numbers, [42, 0]);
assert_eq!(errors_1.children().len(), 1);
assert_eq!(errors_2.children().len(), 2);Here’s a similar example using [Result<T, E>; _] instead:
#[cfg(any(feature = "rust-v1.81", feature = "std"))]
use lazy_errors::{prelude::*, Result};
#[cfg(not(any(feature = "rust-v1.81", feature = "std")))]
use lazy_errors::surrogate_error_trait::{prelude::*, Result};
fn try_parse_each_u8(
input: [Result<&'static str, &'static str>; 2],
) -> Result<[u8; 2]> {
let mut errs = ErrorStash::new(|| "Invalid input");
let numbers = input.try_map_or_stash(u8::from_str, &mut errs);
let numbers: [u8; 2] = try2!(numbers);
Ok(numbers)
}
let numbers = try_parse_each_u8([Ok("42"), Ok("0")]).unwrap();
let errors_1 = try_parse_each_u8([Err("42"), Ok("0")]).unwrap_err();
let errors_2 = try_parse_each_u8([Err("42"), Ok("X")]).unwrap_err();
assert_eq!(numbers, [42, 0]);
assert_eq!(errors_1.children().len(), 1);
assert_eq!(errors_2.children().len(), 2);Note that Err will only be returned
if the array contains an Err element or
if any element of the array gets mapped to an Err value.
Errors that have been added to the error stash before
calling try_map_or_stash will not be considered.
You can call ErrorStash::ok if you want to bail
in case of earlier errors as well:
#[cfg(any(feature = "rust-v1.81", feature = "std"))]
use lazy_errors::{prelude::*, Result};
#[cfg(not(any(feature = "rust-v1.81", feature = "std")))]
use lazy_errors::surrogate_error_trait::{prelude::*, Result};
let mut errs = ErrorStash::new(|| "There were one or more errors");
errs.push("Earlier error"); // Ignored in `try_map_or_stash`
assert!(matches!(errs.ok(), StashedResult::Err(_)));
let numbers: [&str; 1] = ["42"];
let numbers = numbers.try_map_or_stash(u8::from_str, &mut errs);
assert!(matches!(&numbers, StashedResult::Ok(_)));
let numbers1 = numbers.ok().unwrap();
let numbers: [Result<_>; 1] = [Ok("24")];
let numbers = numbers.try_map_or_stash(u8::from_str, &mut errs);
assert!(matches!(&numbers, StashedResult::Ok(_)));
let numbers2 = numbers.ok().unwrap();
assert_eq!(&numbers1, &[42]);
assert_eq!(&numbers2, &[24]);
assert!(matches!(errs.ok(), StashedResult::Err(_)));If you need to map and collect items of an
Iterator<Item = Result<T, E>>,
take a look at try_collect_or_stash and stash_err.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.