diff options
Diffstat (limited to 'codegen/bindings.rs')
-rw-r--r-- | codegen/bindings.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/codegen/bindings.rs b/codegen/bindings.rs index d6b7e0d..5fdfaf3 100644 --- a/codegen/bindings.rs +++ b/codegen/bindings.rs @@ -1,6 +1,7 @@ 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<dyn Error>> @@ -16,9 +17,56 @@ pub fn generate_bindings(dest_file: &Path) -> Result<(), Box<dyn Error>> .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<String> + { + 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::<String>(), + ); + } + + Some(stripped.to_string()) + } +} |