@@ -670,6 +670,87 @@ macro_rules! float_sum_product {
670670integer_sum_product ! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
671671float_sum_product ! { f32 f64 }
672672
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+
673754/// An iterator that always continues to yield `None` when exhausted.
674755///
675756/// Calling next on a fused iterator that has returned `None` once is guaranteed
0 commit comments