shepmaster / snafu

Easily assign underlying errors into domain-specific errors while adding context
https://docs.rs/snafu/
Apache License 2.0
1.45k stars 61 forks source link

Show use of `.fail()` method in user guide #207

Open tkaitchuck opened 4 years ago

tkaitchuck commented 4 years ago

I am not sure is this is a duplicate of https://github.com/shepmaster/snafu/issues/192 but I found myself in the following situation:

match type_of_thing {
  type1 => //do something
  type2 => //something else
  _ => ensure!(false, InvalidType { type: type_of_thing })
}

Of course this doesn't work if the match block is expected to return a result type. I don't really see any neat way to do that if the InvalidType error is going to contain a backtrace.

So from my POV it would be ideal to have some other macro which works like ensure, but doesn't take the boolean.

shepmaster commented 4 years ago

One thing mentioned in #192 is this:

ContextSelector {/* ... */}.fail();

Applied, it would look like

use snafu::{Backtrace, Snafu};

#[derive(Debug, Snafu)]
enum Error {
    InvalidType { v: i32, backtrace: Backtrace },
}

type Result<T, E = Error> = std::result::Result<T, E>;

fn example() -> Result<()> {
    let v = 42;

    match v {
        1 => println!("do something"),
        2 => println!("something else"),
        _ => InvalidType { v }.fail()?,
    };

    Ok(())
}

Does that work for your case?

shepmaster commented 4 years ago

Comparing the two possibilities shows it's only a single character difference:

InvalidType { v }.fail()?
bail!(InvalidType { v })
tkaitchuck commented 4 years ago

Awesome. That works. It just was not very discoverable. Perhaps an example showing that could be added to the docs.