@@ -119,6 +119,7 @@ pub mod structs {
119
119
pub use crate :: cons_tuples_impl:: ConsTuples ;
120
120
pub use crate :: exactly_one_err:: ExactlyOneError ;
121
121
pub use crate :: format:: { Format , FormatWith } ;
122
+ pub use crate :: flatten_ok:: FlattenOk ;
122
123
#[ cfg( feature = "use_std" ) ]
123
124
pub use crate :: grouping_map:: { GroupingMap , GroupingMapBy } ;
124
125
#[ cfg( feature = "use_alloc" ) ]
@@ -194,6 +195,7 @@ mod combinations;
194
195
mod combinations_with_replacement;
195
196
mod exactly_one_err;
196
197
mod diff;
198
+ mod flatten_ok;
197
199
mod format;
198
200
#[ cfg( feature = "use_std" ) ]
199
201
mod grouping_map;
@@ -833,6 +835,30 @@ pub trait Itertools : Iterator {
833
835
adaptors:: filter_map_ok ( self , f)
834
836
}
835
837
838
+ /// Return an iterator adaptor that flattens every `Result::Ok` value into
839
+ /// a series of `Result::Ok` values. `Result::Err` values are unchanged.
840
+ ///
841
+ /// This is useful when you have some common error type for your crate and
842
+ /// need to propogate it upwards, but the `Result::Ok` case needs to be flattened.
843
+ ///
844
+ /// ```
845
+ /// use itertools::Itertools;
846
+ ///
847
+ /// let input = vec![Ok(0..2), Err(false), Ok(2..4)];
848
+ /// let it = input.iter().cloned().flatten_ok();
849
+ /// itertools::assert_equal(it.clone(), vec![Ok(0), Ok(1), Err(false), Ok(2), Ok(3)]);
850
+ ///
851
+ /// // This can also be used to propogate errors when collecting.
852
+ /// let output_result: Result<Vec<i32>, bool> = it.collect();
853
+ /// assert_eq!(output_result, Err(false));
854
+ /// ```
855
+ fn flatten_ok < T , E > ( self ) -> FlattenOk < Self , T , E >
856
+ where Self : Iterator < Item = Result < T , E > > + Sized ,
857
+ T : IntoIterator
858
+ {
859
+ flatten_ok:: flatten_ok ( self )
860
+ }
861
+
836
862
/// Return an iterator adaptor that merges the two base iterators in
837
863
/// ascending order. If both base iterators are sorted (ascending), the
838
864
/// result is sorted.
0 commit comments