Skip to content

Commit bd3a560

Browse files
committed
Add option to generate safe and unsafe conversions for rustified enums
1 parent 07bbd04 commit bd3a560

File tree

10 files changed

+602
-144
lines changed

10 files changed

+602
-144
lines changed

bindgen-cli/options.rs

+24-14
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use bindgen::callbacks::TypeKind;
22
use bindgen::{
33
builder, Abi, AliasVariation, Builder, CodegenConfig, EnumVariation,
44
FieldVisibilityKind, Formatter, MacroTypeVariation, NonCopyUnionStyle,
5-
RegexSet, RustTarget, DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS,
5+
RegexSet, RustEnumOptions, RustTarget, DEFAULT_ANON_FIELDS_PREFIX,
6+
RUST_TARGET_STRINGS,
67
};
78
use clap::error::{Error, ErrorKind};
89
use clap::{CommandFactory, Parser};
@@ -77,6 +78,21 @@ fn parse_abi_override(abi_override: &str) -> Result<(Abi, String), Error> {
7778
Ok((abi, regex.to_owned()))
7879
}
7980

81+
fn parse_rustified_enum(
82+
rustified_enum: &str,
83+
) -> Result<(RustEnumOptions, String), Error> {
84+
let (regex, options) = match rustified_enum.rsplit_once('=') {
85+
Some((regex, options)) => (regex, options),
86+
None => (rustified_enum, ""),
87+
};
88+
89+
let options = options
90+
.parse()
91+
.map_err(|err| Error::raw(ErrorKind::InvalidValue, err))?;
92+
93+
Ok((options, regex.to_owned()))
94+
}
95+
8096
fn parse_custom_derive(
8197
custom_derive: &str,
8298
) -> Result<(Vec<String>, String), Error> {
@@ -150,12 +166,11 @@ struct BindgenCommand {
150166
/// Mark any enum whose name matches REGEX as a global newtype.
151167
#[arg(long, value_name = "REGEX")]
152168
newtype_global_enum: Vec<String>,
153-
/// Mark any enum whose name matches REGEX as a Rust enum.
154-
#[arg(long, value_name = "REGEX")]
155-
rustified_enum: Vec<String>,
156-
/// Mark any enum whose name matches REGEX as a non-exhaustive Rust enum.
157-
#[arg(long, value_name = "REGEX")]
158-
rustified_non_exhaustive_enum: Vec<String>,
169+
/// Mark any enum whose name matches the provided regex as a Rust enum. This parameter takes
170+
/// options in the shape REGEX or REGEX=OPTIONS where OPTIONS can be a comma separated list of
171+
/// options from non_exhaustive, try_from_raw, and from_raw_unchecked.
172+
#[arg(long, value_parser = parse_rustified_enum)]
173+
rustified_enum: Vec<(RustEnumOptions, String)>,
159174
/// Mark any enum whose name matches REGEX as a series of constants.
160175
#[arg(long, value_name = "REGEX")]
161176
constified_enum: Vec<String>,
@@ -523,7 +538,6 @@ where
523538
newtype_enum,
524539
newtype_global_enum,
525540
rustified_enum,
526-
rustified_non_exhaustive_enum,
527541
constified_enum,
528542
constified_enum_module,
529543
default_macro_constant_type,
@@ -690,12 +704,8 @@ where
690704
builder = builder.newtype_global_enum(regex);
691705
}
692706

693-
for regex in rustified_enum {
694-
builder = builder.rustified_enum(regex);
695-
}
696-
697-
for regex in rustified_non_exhaustive_enum {
698-
builder = builder.rustified_non_exhaustive_enum(regex);
707+
for (options, regex) in rustified_enum {
708+
builder = builder.rustified_enum(options, regex);
699709
}
700710

701711
for regex in constified_enum {

bindgen-integration/build.rs

+2
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ fn setup_macro_test() {
192192
.enable_cxx_namespaces()
193193
.default_enum_style(EnumVariation::Rust {
194194
non_exhaustive: false,
195+
safe_conversion: false,
196+
unsafe_conversion: false,
195197
})
196198
.raw_line("pub use self::root::*;")
197199
.raw_line("extern { fn my_prefixed_function_to_remove(i: i32); }")

bindgen-tests/tests/expectations/tests/issue-2646.rs

+100
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bindgen-tests/tests/expectations/tests/libclang-9/struct_typedef_ns.rs

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// bindgen-flags: --rustified-enum 'Plain.*' --rustified-enum 'TryFromRaw.*=try_from_raw' --rustified-enum='FromRawUnchecked.*=from_raw_unchecked' --rustified-enum='Both.*=try_from_raw,from_raw_unchecked' --rustified-enum 'NonExhaustive.*=non_exhaustive'
2+
3+
enum Plain {
4+
Plain1,
5+
Plain2,
6+
Plain3
7+
};
8+
9+
enum TryFromRaw {
10+
TFR1 = -1,
11+
TFR2 = 5,
12+
TFR3
13+
};
14+
15+
enum FromRawUnchecked {
16+
FRU1 = 6,
17+
FRU2 = 10,
18+
FRU3 = 11,
19+
};
20+
21+
enum Both {
22+
Both1,
23+
Both2 = -1,
24+
Both3,
25+
};
26+
27+
enum NonExhaustive {
28+
Ex1,
29+
Ex2,
30+
};

bindgen/codegen/.mod.rs.swp

452 KB
Binary file not shown.

0 commit comments

Comments
 (0)