1use std::{collections::HashMap, fmt::Display, fs::File, path::Path};
2
3use bindgen::Builder;
4use serde::Deserialize;
5
6pub trait BindgenExt {
7 fn config<P>(self, path: P) -> Result<Builder, Box<dyn std::error::Error>>
8 where
9 P: AsRef<Path> + Display;
10}
11
12impl BindgenExt for Builder {
13 fn config<P>(mut self, path: P) -> Result<Builder, Box<dyn std::error::Error>>
14 where
15 P: AsRef<Path> + Display,
16 {
17 println!("cargo:rerun-if-changed={}", path.to_string());
18
19 let cfg: BindgenCfg = serde_yaml::from_reader(File::open(path)?)?;
20
21 for item in cfg.block {
22 self = self.blocklist_item(item);
23 }
24
25 for func in cfg.function.allow {
26 self = self.allowlist_function(func);
27 }
28
29 for func in cfg.function.block {
30 self = self.blocklist_function(func);
31 }
32
33 for var in cfg.variable.allow {
34 self = self.allowlist_var(var);
35 }
36
37 for typ in cfg.typ.allow {
38 self = self.allowlist_type(typ);
39 }
40
41 for typ in cfg.typ.block {
42 self = self.blocklist_type(typ);
43 }
44
45 for typ in cfg.opaque {
46 self = self.opaque_type(typ);
47 }
48
49 for (enm, gen_method) in cfg.enm {
50 self = match gen_method {
51 BindgenEnum::Bitfield => self.bitfield_enum(enm),
52 BindgenEnum::Constified => self.constified_enum(enm),
53 BindgenEnum::ConstifiedModule => self.constified_enum_module(enm),
54 BindgenEnum::NewType => self.newtype_enum(enm),
55 BindgenEnum::Rustified => self.rustified_enum(enm),
56 BindgenEnum::RustifiedNonExhaustive => self.rustified_non_exhaustive_enum(enm),
57 };
58 }
59
60 Ok(self)
61 }
62}
63
64#[derive(Debug, Deserialize, Default)]
65pub struct BindgenCfg {
66 #[serde(default, alias = "blacklist")]
67 pub block: Vec<String>,
68 #[serde(default)]
69 pub function: BindgenFilter,
70 #[serde(default)]
71 pub variable: BindgenFilter,
72 #[serde(rename = "type", default)]
73 pub typ: BindgenFilter,
74 #[serde(rename = "enum", default)]
75 pub enm: HashMap<String, BindgenEnum>,
76 #[serde(default)]
77 pub opaque: Vec<String>,
78}
79
80#[derive(Debug, Deserialize, Default)]
81pub struct BindgenFilter {
82 #[serde(default, alias = "whitelist")]
83 pub allow: Vec<String>,
84 #[serde(default, alias = "blacklist")]
85 pub block: Vec<String>,
86}
87
88#[derive(Debug, Deserialize)]
89#[serde(rename_all = "snake_case")]
90pub enum BindgenEnum {
91 #[serde(alias = "b")]
92 Bitfield,
93 #[serde(alias = "nt")]
94 NewType,
95 #[serde(alias = "r")]
96 Rustified,
97 #[serde(alias = "rne")]
98 RustifiedNonExhaustive,
99 #[serde(alias = "c")]
100 Constified,
101 #[serde(alias = "cm")]
102 ConstifiedModule,
103}