iter.rs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // imag - the personal information management suite for the commandline
  2. // Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
  3. //
  4. // This library is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; version
  7. // 2.1 of the License.
  8. //
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this library; if not, write to the Free Software
  16. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. /// Folds its contents to a result.
  19. pub trait FoldResult: Sized {
  20. type Item;
  21. /// Apply a `FnMut(Self::Item) -> Result<R, E>` to each item. If each
  22. /// application returns an `Ok(_)`, return `Ok(())`, indicating success.
  23. /// Otherwise return the first error.
  24. ///
  25. /// The return type of this function only indicates success with the
  26. /// `Ok(())` idiom. To retrieve the values of your application, include an
  27. /// accumulator in `func`. This is the intended reason for the permissive
  28. /// `FnMut` type.
  29. fn fold_result<R, E, F>(self, func: F) -> Result<(), E>
  30. where F: FnMut(Self::Item) -> Result<R, E>;
  31. }
  32. impl<X, I: Iterator<Item = X>> FoldResult for I {
  33. type Item = X;
  34. fn fold_result<R, E, F>(self, mut func: F) -> Result<(), E>
  35. where F: FnMut(Self::Item) -> Result<R, E>
  36. {
  37. for item in self {
  38. try!(func(item));
  39. }
  40. Ok(())
  41. }
  42. }
  43. #[test]
  44. fn test_fold_result_success() {
  45. let v = vec![1, 2, 3];
  46. let mut accum = vec![];
  47. let result: Result<(), &str> = v.iter().fold_result(|item| {
  48. accum.push(*item * 2);
  49. Ok(*item)
  50. });
  51. assert_eq!(result, Ok(()));
  52. assert_eq!(accum, vec![2, 4, 6]);
  53. }
  54. #[test]
  55. fn test_fold_result_failure() {
  56. let v: Vec<usize> = vec![1, 2, 3];
  57. let mut accum: Vec<usize> = vec![];
  58. let result: Result<(), &str> = v.iter().fold_result(|item| if *item == 2 {
  59. Err("failure")
  60. } else {
  61. accum.push(*item * 2);
  62. Ok(*item)
  63. });
  64. assert_eq!(result, Err("failure"));
  65. assert_eq!(accum, vec![2]);
  66. }