-
Notifications
You must be signed in to change notification settings - Fork 764
Description
Input C/C++ Header
enum my_enum {
RED,
GREEN,
BLUE,
};
Bindgen Invocation
$ bindgen input.h --constified-enum '.*'
Actual Results
/* automatically generated by rust-bindgen */
pub const my_enum_RED: my_enum = 0;
pub const my_enum_GREEN: my_enum = 1;
pub const my_enum_BLUE: my_enum = 2;
pub type my_enum = ::std::os::raw::c_uint;
Expected Results
It would be nice to be able to pass an option like --constified-enum-in-mod 'my_enum'
that tells bindgen to put the matching constified enum inside a module:
pub mod my_enum_mod {
use super::my_enum_type;
pub const RED: my_enum_type = 0;
pub const GREEN: my_enum_type = 1;
pub const BLUE: my_enum_type = 2;
}
pub type my_enum_type = ::std::os::raw::c_uint;
One problem that must be solved is the collision between the type and module name. Some solutions:
- Add a prefix/suffix to the module and/or type name. In the example, "_type" and "_mod" suffixes were added to the type module name.
- Advantages:
- Clearly distinguishes module and type name
- Disadvantage:
- Must use a different name when referring the type vs. the module name
- Advantages:
- Put the type definition in the module.
- Advantage:
- Both the type and module share the same base name
- Disadvantage:
- Both the module and type cannot be imported into the same namespace (because of name collision)
- It is awkward to refer to the type as
my_enum::my_enum
.
- Advantage:
Solutions shown on play.rust-lang.org
Recommendation
Overall, I prefer appending a suffix to the type and using the original name for the module. This way, you can refer to elements of the module like my_enum::RED
. I believe this will overall reduce the amount of typing required, especially since type names can often be elided.
However, this behavior can be controlled with extra options, allowing bindgen users to decide what works best for their situation. The Rust interface to bindgen could also take in callback functions to allow each enum
to be handled on a case-by-case basis.
My recommendation on play.rust-lang.org
Background
I'm currently working on the Rust bindings for Capstone, a disassembly library. Because the same register (for some architectures) can have several names, different enum
variants (for the register id enums) have the same discriminant value. One example is mips_reg
in mips.h
.
I have opted to "constify" the register enum
s. However, in doing so, over 1000 constants are defined in the root of the library, which makes the generated documentation unwieldy.