Skip to content
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

Adding a trait for build/fail #378

Open
l4l opened this issue Jun 18, 2023 · 1 comment
Open

Adding a trait for build/fail #378

l4l opened this issue Jun 18, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@l4l
Copy link

l4l commented Jun 18, 2023

I want to wrap a snafu-managed error with mine that captures some implicit context. Basically I do smth like this:

pub struct MyError {
 context: Context,
 kind: ErrorKind,
}

impl From<ErrorKind> for MyError {
 fn from(kind: ErrorKind) -> Self {
  Self { context: capture(), kind }
 }

#[derive(Snafu)]
pub enum ErrorKind {
  Xyz { .. }
  ..
}

Then in the code I have statements like this return XyzSnafu { .. }.fail().into(). Basically I want to combine that fail() + into() (and similarly for build) into a single call, e.g:

trait MyResExt {
  fn fail_into() -> Error;
}

But here's the problem, there's no generic type bound to implement it for and use fail/build in implementation. So is there any reason why it doesn't exist?

@shepmaster shepmaster added the enhancement New feature or request label Jun 28, 2023
@shepmaster
Copy link
Owner

any reason why it doesn't exist?

The big one would be that using a trait for build or fail would require the user to import that trait first. That's not insurmountable, but it's an annoying papercut. If "inherent traits" were a thing, then this would be an easy win.

Without that, the next best thing would be some kind of adjacent implementation, e.g.

struct X;

impl X {
    fn foo() {}
}

trait TheFooTrait {
    fn foo_from_trait();
}

impl TheFooTrait for X {
    fn foo_from_trait() { self.foo() }
}

Note that this is also annoying as there are different names (IIRC this is required because you can't disambiguate a trait and inherent method of the same name).


captures some implicit context

Would #[snafu(implicit)] help?

In cases where I've wanted to be generic over selectors, I usually end up using the IntoError trait. Note that you may need to use NoneError for your case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants