1use std::fs;
2use std::path::PathBuf;
3
4use bindgen::callbacks::ParseCallbacks;
5#[derive(Debug)]
6struct Cb;
7
8impl ParseCallbacks for Cb {
9 fn process_comment(&self, comment: &str) -> Option<String> {
10 let comment = comment.replace("@retval {", "@retval return_value {");
11 let dox = doxygen_rs::transform(&comment)
12 .trim()
13 .replace('[', r"\[")
14 .replace(']', r"\]")
15 .split('\n')
16 .map(|s| s.trim()) .collect::<Vec<_>>()
18 .join("\n");
19 Some(dox)
20 }
21}
22
23pub fn bind_c2a_builder() -> bindgen::Builder {
24 bindgen::Builder::default()
25 .blocklist_type("max_align_t") .ctypes_prefix("core::ffi")
27 .use_core()
28 .parse_callbacks(Box::new(Cb))
29 .default_enum_style(bindgen::EnumVariation::NewType {
30 is_bitfield: true,
31 is_global: true,
32 })
33}
34
35pub fn bind_c2a(header_path: PathBuf, gen_rs: PathBuf) {
36 let bind = bind_c2a_builder()
37 .header(header_path.to_str().unwrap())
38 .generate()
39 .expect("Unable to generate bindings!");
40 bind.write_to_file(&gen_rs)
41 .expect("Couldn't write bindings!");
42
43 c2a_link_hack(gen_rs);
44}
45
46pub fn c2a_link_hack(gen_rs: PathBuf) {
47 let bind = fs::read_to_string(&gen_rs).unwrap();
49 let bind = bind.replace(
50 "extern \"C\" {",
51 "#[cfg_attr(not(feature=\"no-c2a-link\"),link(name = \"C2A\", kind = \"static\", modifiers = \"-bundle\"))]\nextern \"C\" {",
52 );
53 fs::write(gen_rs, bind).unwrap();
54}