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

Proposal to add a trait for EnumDiscriminants #376

Closed
vpochapuis opened this issue Sep 13, 2024 · 3 comments · Fixed by #377
Closed

Proposal to add a trait for EnumDiscriminants #376

vpochapuis opened this issue Sep 13, 2024 · 3 comments · Fixed by #377

Comments

@vpochapuis
Copy link
Contributor

Hello!
First of all thank you very much for this amazing crate which is very useful for lots of application.

What

I would like to make a proposal to add a Trait implementation to the structs that got derived with EnumDiscriminants in order to use them into generics and get access to the generated enum.

Currently, if my understanding is correct, a new enum is generated from the original name and appended the Discriminants suffix, however i didn't find a convenient way to reference that Type from generics.

Hence this proposal would add a new Trait, EnumDiscriminants:

/// A trait for retrieving the enum generated by [`EnumDiscriminants`] from an associated
/// Type on the original enumeration. This trait can be autoderived by `strum_macros`.
pub trait EnumDiscriminants {
    /// Enum listing the same variants as this enum but without any data fields
    /// Note: maybe we could add some trait bounds based on defaults
    type Discriminants;
}

and related implementation in the macro:

...

        impl #impl_generics #strum_module_path::EnumDiscriminants for #name #ty_generics #where_clause {
            type Discriminants = #discriminants_name;
        }
...

Why

When building applications with Generics, it can be interesting to have access to this generated enum without having to explicitly pass the type.
For example, in my case, I was building a select element for enums in the web using Yew, and wanted to pass to a child that Discriminants Enum through generics, hence we could have trait bounds like so:

impl<T> yew::Component for FormSelect<T>
where
	T: FromStr + strum::EnumDiscriminants + 'static,
	<<T as strum::EnumDiscriminants>::Discriminants: FromStr
		+ strum::VariantNames
		+ AsRef<str>,
	<<<T as strum::EnumDiscriminants>::Discriminants as FromStr>::Err: Debug,

Etc...

This let me save the state of the enum as a lightweight enum without having the potential issue to store additional unused data of enum variants inner types.


If you think this proposal is on par with this crate development, please take a look at this commit from my fork, and if you would like to have a PR , I will do so.
If you think this doesn't fit in this project, please let me know too!

Have a nice day

@mohe2015
Copy link

mohe2015 commented Sep 15, 2024

I also want this, please open a PR. Also #176 seems to be related.

@Peternator7
Copy link
Owner

@vpochapuis thanks for the proposal. Not sure why #176 died (probably lost on my end 😟). Seems reasonable to me, let's do it. One small request, can we implement this trait instead:

/// A trait for retrieving the enum generated by [`EnumDiscriminants`] from an associated
/// Type on the original enumeration. This trait can be autoderived by `strum_macros`.
pub trait IntoDiscriminant {
    /// Enum listing the same variants as this enum but without any data fields
    /// Note: maybe we could add some trait bounds based on defaults
    type Discriminant;

    fn discriminant(&self) -> Self::Discriminant;
}

@vpochapuis
Copy link
Contributor Author

@vpochapuis thanks for the proposal. Not sure why #176 died (probably lost on my end 😟). Seems reasonable to me, let's do it. One small request, can we implement this trait instead:

/// A trait for retrieving the enum generated by [`EnumDiscriminants`] from an associated
/// Type on the original enumeration. This trait can be autoderived by `strum_macros`.
pub trait IntoDiscriminant {
    /// Enum listing the same variants as this enum but without any data fields
    /// Note: maybe we could add some trait bounds based on defaults
    type Discriminant;

    fn discriminant(&self) -> Self::Discriminant;
}

Sure~
Updated at : #377

thanks for taking a look at my proposal~

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

Successfully merging a pull request may close this issue.

3 participants