From 017f98768c66598901f9c95f24369f78185369e9 Mon Sep 17 00:00:00 2001 From: MOZGIII Date: Thu, 1 Aug 2019 01:50:40 +0300 Subject: [PATCH] Add find_result at Iterator --- src/libcore/iter/traits/iterator.rs | 36 +++++++++++++++++++++++++++++ src/libcore/tests/iter.rs | 26 +++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index 7e941267ce824..89a950408a946 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1963,6 +1963,42 @@ pub trait Iterator { }).break_value() } + /// Applies function to the elements of iterator and returns + /// the first non-none result or the first error. + /// + /// + /// # Examples + /// + /// ``` + /// let a = ["1", "2", "lol", "NaN", "5"]; + /// + /// let result = a.iter().find_result(|&s| s.parse()? == 2); + /// + /// assert_eq!(result, Ok(Some(&2))); + /// ``` + /// + /// ``` + /// let a = ["1", "2", "lol", "NaN", "5"]; + /// + /// let result = a.iter().find_result(|&s| s.parse()? == 5); + /// + /// assert!(result.is_err()); + /// ``` + #[inline] + #[unstable(feature = "find_result", reason = "new API", issue = "?")] + fn find_result(&mut self, mut f: F) -> Result, E> where + Self: Sized, + F: FnMut(&Self::Item) -> Result, + { + self.try_for_each(move |x| { + match f(&x) { + Ok(false) => LoopState::Continue(()), + Ok(true) => LoopState::Break(Ok(x)), + Err(x) => LoopState::Break(Err(x)), + } + }).break_value().transpose() + } + /// Searches for an element in an iterator, returning its index. /// /// `position()` takes a closure that returns `true` or `false`. It applies diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index b7b0849e2129b..ce15f05e6c223 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -1258,6 +1258,32 @@ fn test_find_map() { } } +#[test] +fn test_find_result() { +let xs: &[isize] = &[]; + assert_eq!(xs.iter().find_result(testfn), Ok(None)); + let xs: &[isize] = &[1, 2, 3, 4]; + assert_eq!(xs.iter().find_result(testfn), Ok(Some(&2))); + let xs: &[isize] = &[1, 3, 4]; + assert_eq!(xs.iter().find_result(testfn), Err(())); + + let xs: &[isize] = &[1, 2, 3, 4, 5, 6, 7]; + let mut iter = xs.iter(); + assert_eq!(iter.find_result(testfn), Ok(Some(&2))); + assert_eq!(iter.find_result(testfn), Err(())); + assert_eq!(iter.next(), Some(&5)); + + fn testfn(x: &&isize) -> Result { + if **x == 2 { + return Ok(true); + } + if **x == 4 { + return Err(()); + } + Ok(false) + } +} + #[test] fn test_position() { let v = &[1, 3, 9, 27, 103, 14, 11];