I just come up with an idea to improve ergonomic on matching. What if we can write
let tmp: (Option<i32>, Option<String>) = match result {
Ok(v?) | Err(e?) => (v, e),
};
rather than having to write
let tmp: (Option<i32>, Option<String>) = match result {
Ok(v) => (Some(v), None),
Err(e) => (None, Some(e)),
}
? It would be easily to see how this idea can be extended to other enums and more complicated patterns.
This idea was came from this post.
More example:
let tmp: (Option<[u8]>, Option<IOError>) = match asyncresult {
Ready(Ok(data?)) | Pending | Ready(Err(err?)) => (data, err),
}
which desugar to
let tmp: (Option<[u8]>, Option<IOError>) = match asyncresult {
Ready(Ok(data)) => (Some(data),None),
Pending => (None, None),
Ready(Err(err)) => (None, Some(err)),
}
we could also write
let Ok(result?) | Err(err?) = result;
if result.is_some() {
success(result?)
} else if err.is_some() {
fail(err?)
}
so the solution in the post above can be written
pub fn flatten_nested_results<T, E, II, IO>(iter_outer: IO) -> impl Iterator<Item = Result<T, E>>
where
II: Iterator<Item = Result<T, E>>,
IO: Iterator<Item = Result<II, E>>,
{
iter_outer.flat_map(|iter_inner_result| {
let Ok(v?) | Err(e?) = iter_inner_result;
v.into_iter().flatten().chain(r.map(Err))
})
}