@@ -670,6 +670,87 @@ macro_rules! float_sum_product {
670
670
integer_sum_product ! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
671
671
float_sum_product ! { f32 f64 }
672
672
673
+ /// An iterator adapter that produces output as long as the underlying
674
+ /// iterator produces `Result::Ok` values.
675
+ ///
676
+ /// If an error is encountered, the iterator stops and the error is
677
+ /// stored. The error may be recovered later via `reconstruct`.
678
+ struct ResultShunt < I , E > {
679
+ iter : I ,
680
+ error : Option < E > ,
681
+ }
682
+
683
+ impl < I , T , E > ResultShunt < I , E >
684
+ where I : Iterator < Item = Result < T , E > >
685
+ {
686
+ /// Process the given iterator as if it yielded a `T` instead of a
687
+ /// `Result<T, _>`. Any errors will stop the inner iterator and
688
+ /// the overall result will be an error.
689
+ pub fn process < F , U > ( iter : I , mut f : F ) -> Result < U , E >
690
+ where F : FnMut ( & mut Self ) -> U
691
+ {
692
+ let mut shunt = ResultShunt :: new ( iter) ;
693
+ let value = f ( shunt. by_ref ( ) ) ;
694
+ shunt. reconstruct ( value)
695
+ }
696
+
697
+ fn new ( iter : I ) -> Self {
698
+ ResultShunt {
699
+ iter : iter,
700
+ error : None ,
701
+ }
702
+ }
703
+
704
+ /// Consume the adapter and rebuild a `Result` value. This should
705
+ /// *always* be called, otherwise any potential error would be
706
+ /// lost.
707
+ fn reconstruct < U > ( self , val : U ) -> Result < U , E > {
708
+ match self . error {
709
+ None => Ok ( val) ,
710
+ Some ( e) => Err ( e) ,
711
+ }
712
+ }
713
+ }
714
+
715
+ impl < I , T , E > Iterator for ResultShunt < I , E >
716
+ where I : Iterator < Item = Result < T , E > >
717
+ {
718
+ type Item = T ;
719
+
720
+ fn next ( & mut self ) -> Option < Self :: Item > {
721
+ match self . iter . next ( ) {
722
+ Some ( Ok ( v) ) => Some ( v) ,
723
+ Some ( Err ( e) ) => {
724
+ self . error = Some ( e) ;
725
+ None
726
+ }
727
+ None => None ,
728
+ }
729
+ }
730
+ }
731
+
732
+ #[ stable( feature = "iter_arith_traits_result" , since="1.16.0" ) ]
733
+ impl < T , U , E > Sum < Result < U , E > > for Result < T , E >
734
+ where T : Sum < U > ,
735
+ {
736
+ fn sum < I > ( iter : I ) -> Result < T , E >
737
+ where I : Iterator < Item = Result < U , E > > ,
738
+ {
739
+ ResultShunt :: process ( iter, |i| i. sum ( ) )
740
+ }
741
+ }
742
+
743
+ #[ stable( feature = "iter_arith_traits_result" , since="1.16.0" ) ]
744
+ impl < T , U , E > Product < Result < U , E > > for Result < T , E >
745
+ where T : Product < U > ,
746
+ {
747
+ fn product < I > ( iter : I ) -> Result < T , E >
748
+ where I : Iterator < Item = Result < U , E > > ,
749
+ {
750
+ ResultShunt :: process ( iter, |i| i. product ( ) )
751
+ }
752
+ }
753
+
673
754
/// An iterator that always continues to yield `None` when exhausted.
674
755
///
675
756
/// Calling next on a fused iterator that has returned `None` once is guaranteed
0 commit comments