diff -r e43f91244de2 -r f5b168979626 rust/hg-core/src/utils.rs --- a/rust/hg-core/src/utils.rs Wed Jan 11 15:44:21 2023 +0100 +++ b/rust/hg-core/src/utils.rs Wed Jan 11 17:27:19 2023 +0100 @@ -477,3 +477,23 @@ Ok(()) } } + +/// Like `Iterator::filter_map`, but over a fallible iterator of `Result`s. +/// +/// The callback is only called for incoming `Ok` values. Errors are passed +/// through as-is. In order to let it use the `?` operator the callback is +/// expected to return a `Result` of `Option`, instead of an `Option` of +/// `Result`. +pub fn filter_map_results<'a, I, F, A, B, E>( + iter: I, + f: F, +) -> impl Iterator> + 'a +where + I: Iterator> + 'a, + F: Fn(A) -> Result, E> + 'a, +{ + iter.filter_map(move |result| match result { + Ok(node) => f(node).transpose(), + Err(e) => Some(Err(e)), + }) +}