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

AsRef for enum #219

Open
ModProg opened this issue Nov 13, 2022 · 3 comments
Open

AsRef for enum #219

ModProg opened this issue Nov 13, 2022 · 3 comments

Comments

@ModProg
Copy link
Contributor

ModProg commented Nov 13, 2022

This would require you to put the correct attributes on each enum variant, same as for the struct derive:

We would maybe need to be able to specify the actual type here, this would be necessary in case of forward when there are two different types that only share a subset of AsRef implementations.

#[derive(AsRef)]
pub enum Enum {
  #[as_ref(forward)
  Tuple(Forward),
  Struct{
    #[as_ref]
    actual: Actual,
    // ...
  },
  // ...
}
@ModProg ModProg changed the title AsRef for enum AsRef for enum Nov 13, 2022
@JelteF
Copy link
Owner

JelteF commented Dec 19, 2023

Seems like a useful enhancement. Especially the simple case seems easy to implement where both variants have the same type.

@ModProg
Copy link
Contributor Author

ModProg commented Apr 5, 2024

After I ran into this again, I thought I might as well start working on it.

Will only implement the simple case where everything has the same type for now.

I think it would make sense to allow #[as_ref(forward)] and #[as_ref(<types>)] on item level for enums:

#[derive(AsRef)]
#[as_ref(forward)] // or #[as_ref(Type)]
enum Enum {
    NewType(Type),
    Multiple(#[as_ref] Type, Other),
}

I would probably mirror this to structs while keeping placing this information on the field valid:

// current
#[derive(AsRef)]
struct OnField(#[as_ref(forward)] Field, Other);

// will also be valid
#[derive(AsRef)]
#[as_ref(forward)]
struct OnStruct(#[as_ref] Field, Other);

I could also implement a check disallowing it on structs, but IMO there is little value gained by restricting item attributes to structs.

@ModProg
Copy link
Contributor Author

ModProg commented Apr 5, 2024

I'm gonna write down some more thoughts:

if no types are specified, or forward is used, every field annotated with #[as_ref] would be required to be the same type? The issue here could be fmt::Error vs std::fmt::Error, which, in a naive implementation of the check, would yield an error.

Without the use of forward it's pretty simple, this is the direct more, i.e. &field is returned directly. In this case rust would do the type checking for use. We could just use the type of the first variant, and rust would error that the field in the second variant has a different type correctly.

With forward though, I'm not sure, we could either dissallow forward on enums, or we could do the same, use the first fields type, and just call as_ref on all the other fields. This would mean, when using forward on an enum, the condition is, that all other fields implement AsRef for a superset of types that the first field implements AsRef for.

I'd be fine implementing either. We could also avoid this topic by disallowing forward on enums for now, keeping it open to add at a later point.

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

No branches or pull requests

2 participants