Here we describe how Crubit maps enumerations: a Rust unit-only enum or a C++ enum.
enumsFor the following C++ header:
enum Color { kRed, kBlue, kGreen, };
Crubit will generate the following bindings:
#[repr(transparent)] #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, PartialOrd, Ord)] pub struct Color(u32); impl Color { pub const kRed: Color = Color(0); pub const kBlue: Color = Color(1); pub const kGreen: Color = Color(2); } impl From<u32> for Color { fn from(value: u32) -> Color { Color(value) } } impl From<Color> for u32 { fn from(value: Color) -> u32 { value.0 } }
A C++ enum is translated into a set of const items in Rust, because this most accurately represents the fact that C++ enumerations are non-exhaustive (i.e. in C++ any in-range value can be cast to the enumeration, even if it wasn‘t listed in the enum declaration). In other words, C++ behavior doesn’t match Rust enums where “a discriminant in an enum not included in the type definition” is listed as a potential source of Undefined Behavior.
TODO: Consider allowing C++ enums to be marked with an attribute (e.g. [[crubit::exhaustive]]?) and translate them to a Rust enum.
enumsFor the following Rust type:
pub enum Color { Red, Green, Blue, }
Crubit will generate the following bindings:
struct alignas(1) Color final { public: // The Rust type has no `Default` impl. Color() = delete; // The Rust type is not `Copy`. Color(const Color&) = delete; Color& operator=(const Color&) = delete; // All non-`Drop` Rust types are trivially-movable. Color(Color&&) = default; Color& operator=(Color&&) = delete; // The Rust type has no `Drop` impl, // nor requires custom drop glue. ~Color() = default; private: ... };
Note that the generated C++ bindings are currently opaque (b/259984090 and b/280861833 track adding more idiomatic bindings for enumerations). In particular, the C++ side doesn't currently have any direct visibility into the discriminant the Rust enum. Nevertheless, the bindings should cover methods and trait of the Rust enum - for example:
Default trait impl from Rust to the default constructor in C++ (this bullet item is WIP - see b/258249980)