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

Complex enums #70

Open
ethindp opened this issue Jul 16, 2021 · 3 comments
Open

Complex enums #70

ethindp opened this issue Jul 16, 2021 · 3 comments

Comments

@ethindp
Copy link

ethindp commented Jul 16, 2021

I am writing a crate to define data structures for the USB specifications and the device class definitions that go along with them. USB contains requests, which are 8-byte structures stored in host memory and transmitted to the bus via a host controller interface (HCI) like xHCI. The fields for the requests are:

  • bmRequest, which is a bitmap of request attributes that specify where the data will be sent (host to device and vice-versa), the type of the request (standard USB request, class-specific, ...), and the recipient (a device, interface, ...);
  • The request code;
  • Request specific value and index parameters; and
  • The length of data transferred, if any.

The problem is that request codes overlap with each other depending on the type of request (e.g. if its a standard request, then its any of the requests defined in table 9-4 of the USB spec; if its class-specific then its a class-specific code; etc.). An example is a CLEAR_FEATURE request (a standard request with code 0x01) and SET_MIN (a USB audio class-specific request with the same code). Rust does not allow me to define two enumeration discriminants with the same value, but this crate requires me to not use discriminants with variants, so I can't simply define an enumeration variant per request type, and then have sub-variants for each class, for example, to overcome this limitation. Is there an alternative to solve this problem? I could define multiple request types (one per class for example) but that seems wasteful.

@Qyriad
Copy link
Contributor

Qyriad commented Jul 16, 2021

As someone who's familiar with USB: I recommend you make enums for different kinds of requests (standard versus class) different types. In fact I actually recommend you make a different enum for every class.

@ethindp
Copy link
Author

ethindp commented Jul 16, 2021

@Qyriad This was also what I was thinking. However, I cannot then encapsulate them as a central "request" type. My only alternative would be to make separate request types per class, which violates the DRY principal and is something I hesitate to do because I don't want to deal with duplicate code. As such I am seeking an alternative solution that will allow me the freedom of this crate but will also make it possible to centralize the master "request" type, and only make custom request types when a class calls for it.

@hecatia-elegua
Copy link

See #89 + illicitonion/num_enum#81 and now I'm also working on this.

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

No branches or pull requests

3 participants