1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
//! Iterator adapter to stop iteration after the first error is encountered.
//! See documentation for [StopAfterError] for details.

/// Iterator adapter to stop iteration after the first error is encountered.  Lazily yields each item in the iterator up to and including the first error.  Subsequent calls to [Iterator::next()](std::iter::Iterator::next()) return [None](std::option::Option::None).  Use this trait to enable the [stop_after_error()](StopAfterError::stop_after_error()) function for iterators.
///
/// Example:
/// 
/// ```
/// # struct MyError;
/// # impl std::fmt::Display for MyError {
/// # 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// # 		write!(f, "MyError")
/// # 	}
/// # }
/// # impl std::fmt::Debug for MyError {
/// # 	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
/// # 		<MyError as std::fmt::Display>::fmt(self, f)
/// # 	}
/// # }
/// # impl std::error::Error for MyError { }
/// // Use the StopAfterError trait to enable stop_after_error() on iterators.
/// use resultit::StopAfterError;
/// 
/// // Vector of results in which one result is an error.
/// let mut v: Vec<Result<i32, MyError>> = vec![
/// 	Ok(1),
/// 	Ok(2),
/// 	Err(MyError{}),
/// 	Ok(3)
/// ];
/// 
/// // Collection continues even after encountering the error.
/// v = v.into_iter().collect();
/// # assert_eq!(v.len(), 4);
/// println!("{:?}", v);
/// // [Ok(1), Ok(2), Err(MyError), Ok(3)]
/// 
/// // Use stop_after_error() to stop iteration after the first error.
/// v = v.into_iter().stop_after_error().collect();
/// println!("{:?}", v);
/// // [Ok(1), Ok(2), Err(MyError)]
/// # assert_eq!(v.len(), 3);
/// # assert_eq!(*v[0].as_ref().unwrap(), 1);
/// # assert_eq!(*v[1].as_ref().unwrap(), 2);
/// # assert_eq!(v[2].is_err(), true);
/// ```
pub trait StopAfterError {
	/// Iterator adapter to stop iteration after the first error is encountered.
	/// See documentation for [StopAfterError] for details.
	fn stop_after_error<O, E>(self) -> StopAfterErrorIter<Self>
	where
		Self: Iterator<Item=Result<O, E>> + Sized;
}

// Blanket implementation of the StopAfterError trait for all iterators.
// This is what enables us to call stop_after_error() on any iterator.
impl<It> StopAfterError for It
where
	It: Iterator + Sized
{
	fn stop_after_error<O, E>(self) -> StopAfterErrorIter<Self>
	where
		Self: Iterator<Item=Result<O, E>> + Sized
	{
		// Initialize StopAfterErrorIter with the iterator we were called on and the error flag initially set to false.
		StopAfterErrorIter{iter: self, error: false}
	}
}

/// Iterator returned by [stop_after_error()](StopAfterError::stop_after_error()).  You should not need to use this directly.  See the documentation for [StopAfterError] for intended use.
pub struct StopAfterErrorIter<It> {
	// Iterator we are wrapping.
	iter: It,
	
	// Eror flag, set to true upon the first error.
	error: bool
}

impl<It, O, E> Iterator for StopAfterErrorIter<It>
where
	It: Iterator<Item=Result<O, E>>
{
	type Item = Result<O, E>;
	
	// Return the next item in iter until after the first error.
	// Then return None.
	fn next(&mut self) -> Option<Self::Item> {
		match self.error {
			true => None,
			false => {
				match self.iter.next() {
					None => None,
					Some(result) => {
						match result {
							Ok(o) => Some(Ok(o)),
							Err(e) => {
								// Error detected, set the error flag to true.
								self.error = true;
								
								// Return the error.  Now that the error flag is true, the next call to this function will return None.
								Some(Err(e))
							}
						}
					}
				}
			}
		}
	}
}