I assume this is all about having it be a single line and saving characters.
You could use map_or()
, to convert Some(_)
into Err(666)
and None
into Ok(())
. However, this isn't idiomatic, I'd also personally stick to if is_some() { return Err(666); }
, as what that is doing is more clear to the reader.
fn foo(o: Option<i32>) -> Result<(), i32> {
o.map_or(Ok(()), |_| Err(666))?;
Ok(())
}
fn main() {
println!("{:?}", foo(None));
println!("{:?}", foo(Some(42)));
}
Outputs:
Ok(())
Err(666)
You could also create your own ErrOnSome
trait. Naming the method e.g. err_on_some()
it would be more clear and assumable to the reader what's going on, even without knowing the implementation of the err_on_some()
method.
trait ErrOnSome {
fn err_on_some<F, E>(&self, f: F) -> Result<(), E>
where
F: FnOnce() -> Result<(), E>;
}
impl<T> ErrOnSome for Option<T> {
fn err_on_some<F, E>(&self, f: F) -> Result<(), E>
where
F: FnOnce() -> Result<(), E>,
{
match self {
None => Ok(()),
Some(_) => f(),
}
}
}
fn foo(o: Option<i32>) -> Result<(), i32> {
o.err_on_some(|| Err(666))?;
Ok(())
}
Using the same main()
it produces the same output of course.
Edit: Old answer - I misread and thought it was about returning Option
If the contained value is a primitive, i.e. cheap to create, then you could stick to xor()
. However, this isn't idiomatic, I'd also personally stick to if is_some() { return Err(666); }
, as what that is doing is more clear to the reader.
fn foo(o: Option<i32>) -> Option<()> {
o.xor(Some(666))?;
Some(())
}
fn main() {
println!("{:?}", foo(None));
println!("{:?}", foo(Some(42)));
}
Outputs:
Some(123)
None