Skip to content

Instantly share code, notes, and snippets.

@Fiona-J-W
Created November 29, 2018 01:15
Show Gist options
  • Save Fiona-J-W/af04d31ed4a19384e788ed22fdd2a467 to your computer and use it in GitHub Desktop.
Save Fiona-J-W/af04d31ed4a19384e788ed22fdd2a467 to your computer and use it in GitHub Desktop.
use std::error::Error;
pub trait ResultIterator {
type ValueType;
type ErrorType;
fn fold_results<Acc, Fun>(self, init: Acc, fun: Fun) -> Result<Acc, Self::ErrorType>
where
Fun: Fn(Acc, &Self::ValueType) -> Acc;
}
impl<It, V, E> ResultIterator for It
where
It: Iterator<Item = Result<V, E>>,
{
type ValueType = V;
type ErrorType = E;
fn fold_results<Acc, Fun>(self, init: Acc, fun: Fun) -> Result<Acc, Self::ErrorType>
where
Fun: Fn(Acc, &Self::ValueType) -> Acc,
{
let mut acc = init;
for item in self {
match item {
Ok(x) => acc = fun(acc, &x),
Err(e) => return Err(e),
}
}
Ok(acc)
}
}
#[test]
fn test_add() -> Result<(), Box<Error>> {
assert_eq!(
vec!["1", "2", "3"]
.iter()
.map(|i| i.parse::<f64>())
.fold_results(0.0, |a, b| a + b)?,
6.0
);
assert!(
vec!["one", "2", "3"]
.iter()
.map(|i| i.parse::<f64>())
.fold_results(0.0, |a, b| a + b)
.is_err()
);
let data: Vec<Result<f64, Box<Error>>> = vec![Ok(1.0), Ok(2.0), Ok(3.0)];
let iter = data.iter();
assert_eq!(iter.fold_results(0.0, |x, y| x + y)?, 6.0);
Ok(())
}
@Fiona-J-W
Copy link
Author

Errors:

   Compiling fold_results v0.1.0 (/home/florian/dev/rust/fold_results)
error[E0599]: no method named `fold_results` found for type `std::slice::Iter<'_, std::result::Result<f64, std::boxed::Box<dyn std::error::Error>>>` in the current scope
  --> src/main.rs:53:21
   |
53 |     assert_eq!(iter.fold_results(0.0, |x, y| x + y)?, 6.0);
   |                     ^^^^^^^^^^^^
   |
   = note: the method `fold_results` exists but the following trait bounds were not satisfied:
           `std::slice::Iter<'_, std::result::Result<f64, std::boxed::Box<dyn std::error::Error>>> : ResultIterator`
           `&std::slice::Iter<'_, std::result::Result<f64, std::boxed::Box<dyn std::error::Error>>> : ResultIterator`
           `&mut std::slice::Iter<'_, std::result::Result<f64, std::boxed::Box<dyn std::error::Error>>> : ResultIterator`
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `fold_results`, perhaps you need to implement it:
           candidate #1: `ResultIterator`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0599`.
error: Could not compile `fold_results`.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment