It was noted in the await
syntax thread that Option::or_else
mixes poorly with await
(and ?
): https://github.com/rust-lang/rust/issues/57640#issuecomment-457518407
Since one can think of ?
as and_then
, would it make sense for there to be some kind of standard macro or operator for or_else
? Like how C# has the null coalescing operator ??
(which spawned the or_else
conversation) and SQL has the COALESCE
function.
As I’ve been spending a bunch of time with ops::Try
lately, I realized we could do something like this:
#![feature(try_trait)]
macro_rules! coalesce {
($a:expr) => ( $a );
($a:expr , $($c:expr),+) => (
if let Ok(v) = std::ops::Try::into_result($a) {
v
} else {
coalesce!( $($c),+ )
}
);
($($a:expr),+ ,) => (coalesce!($($a),+))
}
fn main() {
assert_eq!( coalesce!(4), 4 );
assert_eq!( coalesce!(Some(4), 2), 4 );
assert_eq!( coalesce!(None, None, None, 2), 2 );
assert_eq!( coalesce!(None, None, Some(3), 2), 3 );
assert_eq!( coalesce!(Err(4), 2), 2 );
assert_eq!( coalesce!(Some(1), unreachable!()), 1 );
assert_eq!( loop { coalesce!(Err(()), break 4) }, 4 );
assert_eq!( loop { break coalesce!(Some(1), break 4) }, 1 );
assert_eq!( coalesce!(4,), 4 );
assert_eq!( coalesce!(Some(4), 2,), 4 );
}
https://play.rust-lang.org/?version=nightly&edition=2018&gist=a6dc7ae213e42e4882781046146ad3dd
Thoughts?
Edit: Adding some links to related things: