bindgen_helpers 0.2.1

Utilities to rename, change case, and fix Rust code generated by bindgen from C headers
Documentation
# Rust bindgen helpers

[![GitHub](https://img.shields.io/badge/github-nyurik/bindgen_helpers-8da0cb?logo=github)](https://github.com/nyurik/bindgen_helpers)
[![crates.io version](https://img.shields.io/crates/v/bindgen_helpers)](https://crates.io/crates/bindgen_helpers)
[![docs.rs](https://img.shields.io/docsrs/bindgen_helpers)](https://docs.rs/bindgen_helpers)
[![crates.io license](https://img.shields.io/crates/l/bindgen_helpers)](https://github.com/nyurik/bindgen_helpers/blob/main/LICENSE-APACHE)
[![CI build](https://github.com/nyurik/bindgen_helpers/actions/workflows/ci.yml/badge.svg)](https://github.com/nyurik/bindgen_helpers/actions)

Utilities to rename, change case, and fix Rust code generated from the C headers using [bindgen](https://rust-lang.github.io/rust-bindgen/).
`Renamer` implements a bindgen callback trait, and currently handles struct/enum/typedef type renames with a `string->string` hashmap.
Additionally, it can rename the enum variant names by removing regex matches, and change identifier case to `PascalCase` to be consistent with the Rust canonical style.

## Usage

```rust
// build.rs
use bindgen::Builder;
use bindgen_helpers::{rename_enum, Renamer};

fn main() {
  // true to enable debug output as warnings
  let mut renamer = Renamer::new(true);
  
  // rename a single item, e.g. a struct, enum, or a typedef
  renamer.rename_item("my_struct", "MyStruct");
  
  // rename an enum and its values
  rename_enum!(
    renamer,
    "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,
};

"#)
    // note that generated regex str includes all the renames, not just enums
    .rustified_enum(renamer.get_regex_str())
    .parse_callbacks(Box::new(renamer))
    .generate().unwrap();
}

//
// This is the approximate code that would be generated by the above:
//

#[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,
}

```

<!-- This code would generate the actual test output, but it is not stable enough to always run

  // Output the generated code to a string.
  // In real code, use .write_to_file("bindings.rs") 
  let mut output = Vec::new();
  bindings.write(Box::new(&mut output)).unwrap();
  let output = String::from_utf8(output).unwrap();

  assert_eq!(output, r##"#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct MyStruct {
    pub a: ::std::os::raw::c_int,
}
#[allow(clippy::unnecessary_operation, clippy::identity_op)]
const _: () = {
    ["Size of MyStruct"][::std::mem::size_of::<MyStruct>() - 4usize];
    ["Alignment of MyStruct"][::std::mem::align_of::<MyStruct>() - 4usize];
    ["Offset of field: MyStruct::a"][::std::mem::offset_of!(MyStruct, a) - 0usize];
};
#[repr(u32)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum MyEnum {
    Yes = 0,
    No = 1,
    Value1 = 2,
    Value2 = 3,
}
"##);
-->

See the list of all [case variants](https://docs.rs/convert_case/latest/convert_case/enum.Case.html) supported by the `convert_case` crate.

## Development

* This project is easier to develop with [just]https://github.com/casey/just#readme, a modern alternative to `make`.
  Install it with `cargo install just`.
* To get a list of available commands, run `just`.
* To run tests, use `just test`.
* On `git push`, it will run a few validations, including `cargo fmt`, `cargo clippy`, and `cargo test`.
  Use `git push --no-verify` to skip these checks.

## License

Licensed under either of

* Apache License, Version 2.0 ([LICENSE-APACHE]LICENSE-APACHE or <http://www.apache.org/licenses/LICENSE-2.0>)
* MIT license ([LICENSE-MIT]LICENSE-MIT or <http://opensource.org/licenses/MIT>)
  at your option.

### Contribution

Unless you explicitly state otherwise, any contribution intentionally
submitted for inclusion in the work by you, as defined in the
Apache-2.0 license, shall be dual licensed as above, without any
additional terms or conditions.