Skip to content

Commit b231dc5

Browse files
committed
allow renaming rules for C enums, structs, and typedefs
```rust // true to enable debug output as warnings let mut ren = Renamer::new(true); // rename a single item, e.g. a struct, enum, or a typedef ren.rename_item("my_struct", "MyStruct"); // rename an enum and its values rename_enum!( ren, "my_enum" => "MyEnum", // rename the enum itself remove: "^I_SAID_", // optionally any number of "remove" regexes remove: "_ENUM$", case: Pascal, // optionally set case convert, defaults to "PascalCase" "MV_IT" => "Value1", // rename a specific value after pattern removal "MV_IT2" => "Value2", // more specific value renames ); let bindings = Builder::default() // in real code, use .header("path/to/header.h") .header_contents("test.h", r#" struct my_struct { int a; }; enum my_enum { I_SAID_YES_ENUM, I_SAID_NO_ENUM, I_SAID_MV_IT_ENUM, I_SAID_MV_IT2_ENUM, }; "#) .rustified_enum(ren.get_regex_str()) .parse_callbacks(Box::new(ren)) .generate().unwrap(); } /////////// generated code #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct MyStruct { pub a: ::std::os::raw::c_int, } #[repr(u32)] #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub enum MyEnum { Yes = 0, No = 1, Value1 = 2, Value2 = 3, } ```
1 parent 97ab915 commit b231dc5

File tree

6 files changed

+355
-3
lines changed

6 files changed

+355
-3
lines changed

Cargo.lock

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

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ cexpr = "0.6"
3030
clang-sys = "1"
3131
clap = "4"
3232
clap_complete = "4"
33+
convert_case = "0.8.0"
3334
env_logger = "0.10.0"
3435
itertools = { version = ">=0.10,<0.14", default-features = false }
3536
libloading = "0.8"

bindgen/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ cexpr.workspace = true
3232
clang-sys = { workspace = true, features = ["clang_11_0"] }
3333
clap = { workspace = true, features = ["derive"], optional = true }
3434
clap_complete = { workspace = true, optional = true }
35+
convert_case.workspace = true
3536
itertools = { workspace = true }
3637
log = { workspace = true, optional = true }
3738
prettyplease = { workspace = true, optional = true, features = ["verbatim"] }

bindgen/ir/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -395,15 +395,15 @@ pub(crate) struct BindgenContext {
395395
/// Whether a bindgen float16 was generated
396396
generated_bindgen_float16: Cell<bool>,
397397

398-
/// The set of `ItemId`s that are allowlisted. This the very first thing
398+
/// The set of [`ItemId`]s that are allowlisted. This the very first thing
399399
/// computed after parsing our IR, and before running any of our analyses.
400400
allowlisted: Option<ItemSet>,
401401

402-
/// Cache for calls to `ParseCallbacks::blocklisted_type_implements_trait`
402+
/// Cache for calls to [`crate::callbacks::ParseCallbacks::blocklisted_type_implements_trait`]
403403
blocklisted_types_implement_traits:
404404
RefCell<HashMap<DeriveTrait, HashMap<ItemId, CanDerive>>>,
405405

406-
/// The set of `ItemId`s that are allowlisted for code generation _and_ that
406+
/// The set of [`ItemId`]s that are allowlisted for code generation _and_ that
407407
/// we should generate accounting for the codegen options.
408408
///
409409
/// It's computed right after computing the allowlisted items.

bindgen/lib.rs

+33
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ mod features;
4646
mod ir;
4747
mod parse;
4848
mod regex_set;
49+
mod renamer;
4950

5051
pub use codegen::{
5152
AliasVariation, EnumVariation, MacroTypeVariation, NonCopyUnionStyle,
@@ -55,6 +56,7 @@ pub use ir::annotations::FieldVisibilityKind;
5556
pub use ir::function::Abi;
5657
#[cfg(feature = "__cli")]
5758
pub use options::cli::builder_from_flags;
59+
pub use renamer::{Case, IdentRenamer, Renamer, RxSet};
5860

5961
use codegen::CodegenError;
6062
use features::RustFeatures;
@@ -1312,6 +1314,37 @@ impl callbacks::ParseCallbacks for CargoCallbacks {
13121314
}
13131315
}
13141316

1317+
/// Macro to help define renaming rules for an enum and its values. See example in the [`renamer`] documentation.
1318+
#[macro_export]
1319+
macro_rules! rename_enum {
1320+
( $cb:expr,
1321+
$c_name:literal => $rust_name:literal
1322+
$(, remove: $remove:literal)*
1323+
$(, case: $case:ident)?
1324+
$(, $itm:literal => $ren:literal)*
1325+
$(,)?
1326+
) => {
1327+
$cb.rename_item($c_name, $rust_name);
1328+
#[allow(clippy::needless_update)]
1329+
$cb.rename_enum_val(
1330+
Some(concat!("enum ", $c_name)),
1331+
$crate::IdentRenamer {
1332+
remove: {
1333+
let patterns: Vec<&str> = vec![$($remove),*];
1334+
if patterns.is_empty() {
1335+
None
1336+
} else {
1337+
Some($crate::RxSet::new(&patterns).expect("Unable to compile regex set for remove parameter"))
1338+
}
1339+
},
1340+
$( case: Some($crate::Case::$case), )?
1341+
renames: vec![$( ($itm.into(), $ren.into()), )*].into_iter().collect(),
1342+
..$crate::IdentRenamer::default_case($crate::Case::Pascal)
1343+
}
1344+
);
1345+
};
1346+
}
1347+
13151348
/// Test `command_line_flag` function.
13161349
#[test]
13171350
fn commandline_flag_unit_test_function() {

0 commit comments

Comments
 (0)