Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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 #[cpp_enum] 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], #[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)]:

// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

use crubit_annotate::cpp_enum;
use open_enum::open_enum;

#[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:

// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

// Automatically @generated C++ bindings for the following Rust crate:
// example_crate_golden
// Features: custom_ffi_types, non_unpin_ctor, std_unique_ptr, std_vector,
// supported

// clang-format off
#ifndef THIRD_PARTY_CRUBIT_EXAMPLES_RUST_CPP_ENUM_EXAMPLE_CRATE_GOLDEN
#define THIRD_PARTY_CRUBIT_EXAMPLES_RUST_CPP_ENUM_EXAMPLE_CRATE_GOLDEN

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
#include "support/annotations_internal.h"

#include <cstdint>

namespace example_crate {

// CRUBIT_ANNOTATE: cpp_enum=enum class
//
// Generated from:
// examples/rust/cpp_enum/example.rs;l=13
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),
};

}  // namespace example_crate
#pragma clang diagnostic pop
#endif  // THIRD_PARTY_CRUBIT_EXAMPLES_RUST_CPP_ENUM_EXAMPLE_CRATE_GOLDEN