Skip to content

Commit

Permalink
feat(report): Implement WrapError for Option (#409)
Browse files Browse the repository at this point in the history
Fixes: #408

Implement `WrapError` for `Option<T>`. This is inline with `anyhow` that
also implements `Context` for `Option<T>`.

The implementation requires us to introduce a `DisplayError` internal
only type, that creates an error from a type that only implements
`Display` (`Report::from_adhoc` requires the type to also implement
`Debug`, but `WrapError` only requires it to implement `Display`).

For this I copied `MessageError` and adapted it to implement `Debug`
using the underlying type's `Display` impl. This is a bit of a hack, but
anyhow does [something similar][1].

[1]: https://docs.rs/anyhow/latest/src/anyhow/wrapper.rs.html#34
  • Loading branch information
jalil-salame authored Nov 27, 2024
1 parent 465e6b6 commit 7fae60f
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/eyreish/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,44 @@ mod ext {
}
}

impl<T> WrapErr<T, std::convert::Infallible> for Option<T> {
fn wrap_err<D>(self, msg: D) -> Result<T, Report>
where
D: Display + Send + Sync + 'static,
{
match self {
Some(t) => Ok(t),
None => Err(Report::from(crate::eyreish::wrapper::DisplayError(msg))),
}
}

fn wrap_err_with<D, F>(self, msg: F) -> Result<T, Report>
where
D: Display + Send + Sync + 'static,
F: FnOnce() -> D,
{
match self {
Some(t) => Ok(t),
None => Err(Report::from(crate::eyreish::wrapper::DisplayError(msg()))),
}
}

fn context<D>(self, msg: D) -> Result<T, Report>
where
D: Display + Send + Sync + 'static,
{
self.wrap_err(msg)
}

fn with_context<D, F>(self, msg: F) -> Result<T, Report>
where
D: Display + Send + Sync + 'static,
F: FnOnce() -> D,
{
self.wrap_err_with(msg)
}
}

impl<T, E> WrapErr<T, E> for Result<T, E>
where
E: ext::Diag + Send + Sync + 'static,
Expand Down
24 changes: 24 additions & 0 deletions src/eyreish/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ use crate::{Diagnostic, LabeledSpan, Report, SourceCode};

use crate as miette;

#[repr(transparent)]
pub(crate) struct DisplayError<M>(pub(crate) M);

impl<M> Debug for DisplayError<M>
where
M: Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.0, f)
}
}

impl<M> Display for DisplayError<M>
where
M: Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(&self.0, f)
}
}

impl<M> StdError for DisplayError<M> where M: Display + 'static {}
impl<M> Diagnostic for DisplayError<M> where M: Display + 'static {}

#[repr(transparent)]
pub(crate) struct MessageError<M>(pub(crate) M);

Expand Down

0 comments on commit 7fae60f

Please sign in to comment.