bindgen_cfg/
lib.rs

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}