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.