Generating C++ enums from Rust enums
By default, a Rust enum is mapped to an opaque C++ type (see C++ bindings for
Rust enums). However, Crubit can try to map Rust enums to C++
enums if requested using the #[crubit_annotate::cpp_enum(kind = "enum")] or
#[crubit_annotate::cpp_enum(kind = "enum class")] attribute. C++ code can use
such enums like any other C++ enum.
But #[cpp_enum] cannot be used with exhaustive Rust enums. It may only be
used on non-exhaustive enums, such as those created with #[open_enum] from the
open_enum crate. Therefore, to generate C++ enum bindings, you must annotate
your Rust enum with #[cpp_enum(kind = ...)], #[repr(...)] (where ... is an
integer type like i32), and #[open_enum].
C++ enums are non-exhaustive by default, meaning they can hold values other than
the explicitly named enumerators. #[open_enum] generates a Rust enum that is
similarly non-exhaustive. Additionally, C++ allows multiple enumerators to have
the same value, which can be enabled in Rust by using
#[open_enum(allow_alias)].
Example
Given the following Rust crate that uses #[cpp_enum] and
#[open_enum(allow_alias)]:
#[open_enum(allow_alias)]
#[cpp_enum(kind = "enum class")]
#[repr(i32)]
#[derive(Copy, Clone, Default)]
pub enum Color {
Red,
Blue,
Green = 5,
Gray = 5,
Magenta = 7,
}
Crubit will generate the following bindings:
// CRUBIT_ANNOTATE: cpp_enum=enum class
enum class CRUBIT_INTERNAL_RUST_TYPE(
":: example_crate_golden :: Color") Color : ::std::int32_t {
Red = INT32_C(0),
Blue = INT32_C(1),
Green = INT32_C(5),
Gray = INT32_C(5),
Magenta = INT32_C(7),
};