-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Something like ContextCompat
but for options only
#41
Comments
I've just noticed |
I think it should be possible to write this trait impl outside of
I don't think there was a reason, if I had thought about it at the time leaving out |
Noticed the same thing as well.. +1 for /* as for style preference, I wish |
I think the libs team is actively planning on adding methods for converting Here: use std::fmt;
trait Context: Sized {
type Return;
fn context<D>(self, msg: D) -> Self::Return
where
D: fmt::Display + fmt::Debug + Send + Sync + 'static,
{
self.with_context(|| msg)
}
fn with_context<F, D>(self, op: F) -> Self::Return
where
D: fmt::Display + fmt::Debug + Send + Sync + 'static,
F: FnOnce() -> D;
}
impl Context for bool {
type Return = Result<(), eyre::Report>;
fn with_context<F, D>(self, op: F) -> Self::Return
where
D: fmt::Display + fmt::Debug + Send + Sync + 'static,
F: FnOnce() -> D,
{
if self {
Ok(())
} else {
Err(eyre::eyre!(op()))
}
}
}
impl<T> Context for Option<T> {
type Return = Result<T, eyre::Report>;
fn with_context<F, D>(self, op: F) -> Self::Return
where
D: fmt::Display + fmt::Debug + Send + Sync + 'static,
F: FnOnce() -> D,
{
self.ok_or_else(|| eyre::eyre!(op()))
}
}
fn main() {
let res: Result<(), eyre::Report> = false.context("hi");
let report = res.unwrap_err();
eprintln!("Error: {:?}", report);
let res: Result<(), eyre::Report> = None.context("hi");
let report = res.unwrap_err();
eprintln!("Error: {:?}", report);
} |
Yes, there's currently an ongoing bikeshed in rust repo, looks like it'll take another year... and it will be another call. The example you've provided is pretty much what I suggested, it's just that I really enjoyed the fact that let x = y.checked_div(z).context("division error")?; Why? Because there's no macros and no extra function calls. The resulting syntax is as simple as possible, especially when you have tons of these. With booleans, the idea is the same, is when you have many condition checks each of which may generate an error, you could simply have: (a < 1).context("too small")?;
(a > 100).context("too large")?;
(a % 2 = 0).context("too even")?; (on the other hand, I have to admit that at least you can implement what's suggested above without overlapping with the existing |
This goes back to one of the fundamental differences between how I like to mentally model errors and how anyhow / prior crates handle it. A big motivator for me writing let x = y.checked_div(z).ok_or_else(|| eyre!("division error"))?;
I appreciate that this version is slightly more verbose, but the verbosity is not without value here. I feel it's important to differentiate between errors that are wrapped and those that are newly created when an option is None. |
@yaahc Apologies if not directly related (please let me know if I should post this to
Ideally, it should instead look like this:
Hence my initial thinking - if something like this was embedded into Now, there's |
Edit: the problem above is solved via
Then you get |
looks like you figured it out but yea, this is the second release in a row for As for the custom frame filters, I have for the most part been pretty conservative about which functions I add to the set of frame filters. Filtering out relevant frames would probably piss ppl off a lot more than having slightly noisier backtraces. That said, I think it might be a good idea to copy |
Yea - great idea re: filter nursery. I have a similar frame filter list (almost identical, in fact) to the one you've posted above, but with |
I'm gonna go ahead and close this issue as resolved |
I like the idea of differentiating between options from errors
WrapErr
intent to bring. But I still like simplicity ofOption.context(..)?
. So I'd prefer to use.wrap_err
on errors and.context
on options. Actually after reading the docs I thoughtContextCompat
works exactly this way, implementing.context
for options only. But it happens to bring full compatibility withanyhow.Context
, so the compiler won't guide me through changing.context
to.wrap_err
for errors. Would you consider adding something likeOptionContext
which would add.context
for options only?To summarize:
WrapErr
brings.wrap_err
for errors only, but no.context
OptionContext
brings.context
for options onlyWhat do you think?
The text was updated successfully, but these errors were encountered: