Uh… what?
So I understand the type signature she’s asking for is
Iter<Result<T, E>> -> Result<Iter<T>, Iter<E>>
This suggestion could really use some use case examples. It sounds sufficiently obscure to me that I wouldn’t complain about having to write my own a function for this
Also, where does the name
evert
come from?I can see this being useful for parsing. You often want to report all of the parsing errors to the user in one go, so collecting them into a list or iterator is useful.
But yeah, still relatively obscure.
And I’m guessing, “evert” is simply the respective English word: https://en.wiktionary.org/wiki/evert
As a non-native speaker, I didn’t know that word either…I’m a native english speaker and I didn’t know that word :o
deleted by creator
I think she is talking about this functionality which already exists. It is not very intuitive though.
let res = my_collection .iter() .map(|x| method_that_returns_result(x)) .collect::<Result<Vec<T>, Error>>()?;
So it turns a
Vec<Result, Error>
intoResult<Vec<T>, Error>
, and you can turn it intoVec<T
> simply with?
. Otherwise you would probably need a for loop.do you mean
Vec<Result<T, Error>>
? why would an error type be the second type argument for aVec
?
i might try
let res = collection.into_iter().map(|item| item.fallible_operation()).fold(Ok(Vec::new()), |acc, res| { match (acc, res) { (Ok(mut vec), Ok(item)) => { vec.push(item); Ok(vec) (Err(mut vec), Err(error)) => { vec.push(error); Err(vec) } (Ok(_), Err(error)) => Err(vec![error]), _ => acc, } });
Maybe expand it with
pub trait Evert<T, E> { fn evert(self) -> Result<Vec<T>, Vec<E>>; } impl<I, T, E> Evert<T, E> for I where I: IntoIterator<Item = Result<T, E>>, { fn evert(self) -> Result<Vec<T>, Vec<E>> { self.into_iter().fold(/* implementation from above */) } } fn main() { let result = vec![Ok(1), Err(3), Ok(4), Err(8)].evert(); assert_eq!(result, Err(vec![3, 8])); }