Report all errors (or only the first error)
Make this compile and pass tests:
#![allow(unused)] fn main() { trait Collects { type Fast; type Slow; type Output; fn create(&self, next: i32) -> Result<Self::Slow, Self::Fast>; fn update(&self, slow: &mut Self::Slow, next: i32); fn regularize(&self, result: Result<Result<Vec<i32>, Self::Slow>, Self::Fast>) -> Result<Vec<i32>, Self::Output>; } struct First; struct All; impl Collects for First { type Fast = i32; type Slow = std::convert::Infallible; type Output = i32; fn create(&self, next: i32) -> Result<Self::Slow, Self::Fast> { Err(next) } fn update(&self, slow: &mut Self::Slow, _next: i32) { match *slow {} } fn regularize(&self, result: Result<Result<Vec<i32>, Self::Slow>, Self::Fast>) -> Result<Vec<i32>, Self::Output> { result.map(|r| r.unwrap_or_else(|slow| match slow {} )) } } impl Collects for All { type Fast = std::convert::Infallible; type Slow = Vec<i32>; type Output = Vec<i32>; fn create(&self, next: i32) -> Result<Self::Slow, Self::Fast> { let mut slow = vec![]; slow.push(next); Ok(slow) } fn update(&self, slow: &mut Self::Slow, next: i32) { slow.push(next) } fn regularize(&self, result: Result<Result<Vec<i32>, Self::Slow>, Self::Fast>) -> Result<Vec<i32>, Self::Output> { result.unwrap_or_else(|fast| match fast {}) } } fn first() -> impl Collects<Output = i32> { First } fn all() -> impl Collects<Output = Vec<i32>> { All } fn _only_postivie<C: Collects>(numbers: Vec<i32>, c: &C) -> Result<Result<Vec<i32>, C::Slow>, C::Fast> { let mut state = Ok(vec![]); for x in numbers { state = if x > 0 { state.map(|mut vec| {vec.push(x); vec}) } else { Err(match state { Ok(_) => c.create(x)?, Err(mut slow) => { c.update(&mut slow, x) ; slow } }) } } Ok(state) } fn only_positive<C: Collects>(numbers: Vec<i32>, c: C) -> Result<Vec<i32>, C::Output> { c.regularize(_only_postivie(numbers, &c)) } assert_eq!(only_positive(vec![1, -1, 2, -4], first()), Err(-1)); assert_eq!(only_positive(vec![1, 2, 3], first()), Ok(vec![1, 2, 3])); assert_eq!(only_positive(vec![1, -1, 2, -4], all()), Err(vec![-1, -4])); assert_eq!(only_positive(vec![1, 2, 3], all()), Ok(vec![1, 2, 3])); }
only_positive(..., first())
should short-circuit on first non-positive number.only_positive(..., all())
must collect all non-positive numbers.