A Rust enum is mapped to an opaque C++ type.
To receive C++ bindings, the enum must be movable in C++. See
Movable Types.
Given the following Rust crate:
{{ #include ../../examples/rust/enum/example.rs }}
Crubit will generate the following bindings:
{{ #include ../../examples/rust/enum/example_generated.h }}
A repr(i32) or fieldless repr(C) enum is very similar to a C++ enum.
However, Rust enums are exhaustive: any value not explicitly listed in the
enum declaration does not exist, and it is
undefined behavior
to attempt to create one.
C++ enums, in contrast, are "non-exhaustive": a C++ enum can have any
value supported by the underlying type, even one not listed in the enumerators.
For example, if the above example were a C++ enum, static_cast<Color>(42)
would be a valid instance of Color, even though neither Red, Blue, nor
Green have that value.
In order to prevent invalid Rust values from being produced by C++, a C++ enum
cannot be used to represent a Rust enum. Instead, the C++ bindings are a
struct, even for fieldless enums.
To receive C++ bindings, the enum must be movable in C++. See
Movable Types.
C++ bindings for Rust enums provide a static Make<variant name> method for
each of enum variants. These methods can be used to construct an enum value
with the corresponding variant.
Given the following Rust crate:
{{ #include ../../examples/rust/enum_with_payload/example.rs }}
Crubit will generate the following bindings:
{{ #include ../../examples/rust/enum_with_payload/example_generated.h }}
The following bugs track future work in this area:
- b/487357254: Constructing variants with a struct payload
- b/489085607: Bindings for constructing enums should be
constexpr