use std::error::Error; use std::path::Path; use bindgen::callbacks::ParseCallbacks; use bindgen::{CodegenConfig, MacroTypeVariation}; pub fn generate_bindings(dest_file: &Path) -> Result<(), Box> { println!("cargo:rerun-if-changed=gl.h"); let bindings = bindgen::Builder::default() .header("gl.h") .default_macro_constant_type(MacroTypeVariation::Signed) .with_codegen_config(CodegenConfig::all() & !CodegenConfig::FUNCTIONS) .allowlist_type("GL.*") .allowlist_type("_cl_.*") .allowlist_var("GL_.*") .blocklist_item("GL_Z4.*") .blocklist_item("GL_Z6.*") .parse_callbacks(Box::new(Callbacks)) .generate()?; bindings.write_to_file(dest_file)?; Ok(()) } #[derive(Debug)] struct Callbacks; impl ParseCallbacks for Callbacks { fn item_name(&self, original_item_name: &str) -> Option { let stripped = original_item_name.strip_prefix("GL_")?; if stripped.starts_with(|character: char| character.is_ascii_digit()) { let digit_cnt = stripped .chars() .filter(|character| character.is_ascii_digit()) .count(); let digits = stripped .chars() .take_while(|character| character.is_ascii_digit()) .map(|character| match character { '0' => "zero", '1' => "one", '2' => "two", '3' => "three", '4' => "four", '5' => "five", '6' => "six", '7' => "seven", '8' => "eight", '9' => "nine", _ => unreachable!(), }); return Some( digits .map(|digit| digit.chars()) .flatten() .map(|character| character.to_ascii_uppercase()) .chain(stripped.chars().skip(digit_cnt)) .collect::(), ); } Some(stripped.to_string()) } }