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

[new feature] bounds for generic error types #9

Open
lovasoa opened this issue Nov 23, 2018 · 5 comments
Open

[new feature] bounds for generic error types #9

lovasoa opened this issue Nov 23, 2018 · 5 comments
Labels
enhancement New feature or request

Comments

@lovasoa
Copy link
Owner

lovasoa commented Nov 23, 2018

It would be great to be able to specify bounds in generic errors. Something like:

custom_error!{MyError<T: Display + Debug>
    Bad{param: T}  = @{ param.to_string() },
}
@lovasoa lovasoa changed the title [new feature] [new feature] bounds for generic error types Nov 23, 2018
@lovasoa lovasoa added the enhancement New feature or request label Nov 23, 2018
@sobolevn
Copy link

What's is the status of this issue? Is it possible to use generics in custom_error! macro?

@lovasoa
Copy link
Owner Author

lovasoa commented Sep 24, 2019

No work has been done on this so far, and I think it is non-trivial to add. If you want to have a shot at implementing it, this will be welcome.

@sobolevn
Copy link

Sorry, I guess am not good enough with rust yet to handle this kind of task 😞

Anyway, thanks for the clarification. It would be super useful to have!

@tokcum
Copy link

tokcum commented Nov 10, 2022

I'm willing to look into this. I would like to use custom_error in a project because it is free of unsafe code but I need support for generics.

I'll give it a try ... any support (even immature ideas) appreciated.

@tokcum
Copy link

tokcum commented Nov 11, 2022

This is my first approach:

When custom_error supports generics we could write this

custom_error!{MyError<T>
    Unknown{code: T} = "unknown error with code {code}.",
    Err41            = "Sit by a lake"
}

instead of

use std::fmt::{Debug, Display};

#[derive(Debug)]
enum MyError<T> {
    Unknown { code: T },
    Err41,
}

impl<T: Debug> std::error::Error for MyError<T> {}

impl<T: Debug> Display for MyError<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter)
           -> std::fmt::Result {
        match self {
            MyError::Unknown { code } => write!(f, "unknown error with code {:?}." , code),
            MyError::Err41 => write!(f, "Sit by a lake")
        }
    }
}

Let me share my reasoning with you: Rust Std says: "Display is for user-facing output, and so cannot be derived." Taking this into account, I think it doesn't make much sense to try to automatically generate an implementation of Display for a generic type T. That's the reason why there is no derive for Display. Please correct me if I'm wrong.

I see three options:

  1. We could tell the user to implement Display if he needs to use custom_error with a generic T.
  2. We could switch from the default formatter {} to the already derived Debug implementation providing us with {:?}, but only in cases where the developer uses custom_error with a generic T.
  3. We could provide the user an interface which allows her to tell us how to display T without much boilerplate.

Thinking about the first option: what is the point to use custom_error at all, when the user has to provide her own implementation of Display?

The second option is drafted in the example above. Looks pretty straight forward but doesn't allow user friendly output, thus it does not match the expectation of Display raised by Rust Std.

I'm not sure about the third option. How could this look like? Let the user define a closure or accept a formatter string in the Error definition?

Let me know what you think.

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

3 participants