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

Generate Rust enums from bindgen output #32

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Remmirad
Copy link

@Remmirad Remmirad commented Apr 6, 2023

C enums handled by bindgen are translated into something like this: pub const c_enum_name_enum_variant. This is a bit annoying when someone wants to use them as a correct Rust enum, because one has to basically rewrite and maintain a separate Rust enum. The idea here is now to provide a list inside of build.rs just like with the macros where enums can be registered to be translated into Rust. build.rs will scan the bindgenoutput for the c enums and create the corresponding Rust enums in enums.rs

This would have the side effect, that the enum list would automatically updated with RIOT. I am not 100% sure this is desirable but if one would mark the enums as non_exhaustive "older" Rust code should still work with new RIOT versions. My hope is that this could make things a bit easier to maintain and build.

@chrysn
Copy link
Member

chrysn commented Oct 20, 2023

Sorry, I completely missed that this was submitted. It'd be certainly practical to have better ergonomics than doing this manually in riot-wrappers.

I'm not sure how this is best usable: There is no TryFrom<ux> / Into<ux>, and while the latter can be done using as usize, the former can't be done. So how would you use this in practice? Rely on RIOT APIs not returning values that are not part of the enum? (This might go over better with a DEVELHELP check).

This looks very similar to what the rustified_enum output that bindgen can produce. (Examples of the variants are available). Couldn't we use that instead of doing it manually? (It has about the same downsides).

What riot-wrappers sometimes does is to add an Other variant (in other places, fallible conversion is used). Would that make sense to do here right away (by adding an enum variant, or by providing a fallible conversion method)?

@Remmirad
Copy link
Author

Remmirad commented Oct 20, 2023

No problem it's not very important :)

For the TryFrom and Into traits couldn't those be generated alongside the enums (I could try to implement this). It might be just a big match statement? (like the fallible conversion you linked)

The rustified enum output would rely on RIOT never returning "invalid"-enum-values if I read the info from the link you provided correctly? So to me it seems safer to keep the int return/enum types, generate the Rust-variants and let the wrapper around the foreign-function decide how to proceed e.g. by calling TryFrom for the Rust-enum-variant:

let c_enum: i32 = riot_sys::some_c_function();
return RustEnum::try_from(c_enum);

This should basically be what riot-wrappers is doing with the fallible conversion enums just automated.

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 this pull request may close these issues.

2 participants