pub trait TryCollectOrStash<T, E, S, I>where
E: Into<I>,{
// Required method
fn try_collect_or_stash<C>(self, stash: &mut S) -> StashedResult<'_, C, I>
where C: FromIterator<T>;
}
Expand description
Adds the try_collect_or_stash
method on
Iterator<Item = 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_collect_or_stash<C>(self, stash: &mut S) -> StashedResult<'_, C, I>where
C: FromIterator<T>,
fn try_collect_or_stash<C>(self, stash: &mut S) -> StashedResult<'_, C, I>where
C: FromIterator<T>,
Counterpart to Iterator::try_collect
from the Rust standard library
that will not short-circuit,
but instead move all Err
items into an error stash.
This method evaluates all items in the Iterator
.
Each time an Err
value is encountered,
it will be put into the supplied error stash
and iteration will continue with the next item.
This method will return a StashedResult::Ok
containing a collection of all Result::Ok
items.
If there are one or more Result::Err
items,
all of them will be added to the supplied error stash, and
this method will return a StashedResult::Err
containing that error stash 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 parse_each_u8(tokens: &[&str]) -> Result<Vec<u8>> {
let mut errs = ErrorStash::new(|| "There were one or more errors");
let numbers: StashedResult<Vec<u8>> = tokens
.iter()
.map(|&s| u8::from_str(s))
.try_collect_or_stash(&mut errs);
let numbers: Vec<u8> = try2!(numbers);
Ok(numbers)
}
let empty = parse_each_u8(&[]).unwrap();
let numbers = parse_each_u8(&["1", "42", "3"]).unwrap();
let errors_1 = parse_each_u8(&["1", "X", "3"]).unwrap_err();
let errors_2 = parse_each_u8(&["1", "X", "Y"]).unwrap_err();
let errors_3 = parse_each_u8(&["X", "Y", "Z"]).unwrap_err();
assert_eq!(&empty, &[]);
assert_eq!(&numbers, &[1, 42, 3]);
assert_eq!(errors_1.children().len(), 1);
assert_eq!(errors_2.children().len(), 2);
assert_eq!(errors_3.children().len(), 3);
Note that Err
will only be returned
if the iterator contains an Err
element.
Errors that have been added to the error stash before
calling try_collect_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_collect_or_stash`
assert!(matches!(errs.ok(), StashedResult::Err(_)));
let numbers = ["42"]
.iter()
.map(|&s| u8::from_str(s))
.try_collect_or_stash::<Vec<u8>>(&mut errs);
assert!(matches!(&numbers, StashedResult::Ok(_)));
let numbers = numbers.ok().unwrap();
assert_eq!(&numbers, &[42]);
assert!(matches!(errs.ok(), StashedResult::Err(_)));
If you need to transform an Iterator<Item = Result<T, E>>
into an Iterator<Item = T>
and
call a method before collecting all T
items,
take a look at stash_err
.
If you want to map elements of a fixed-size array in a similar manner,
take a look at try_map_or_stash
.
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.