1use bindgen::callbacks::*;
2
3#[derive(Debug)]
4pub struct RemovePrefixParseCallback {
5    pub remove_prefix: Option<String>,
6}
7
8impl RemovePrefixParseCallback {
9    pub fn new(prefix: &str) -> Self {
10        RemovePrefixParseCallback {
11            remove_prefix: Some(prefix.to_string()),
12        }
13    }
14}
15
16impl ParseCallbacks for RemovePrefixParseCallback {
17    fn generated_name_override(&self, item_info: ItemInfo) -> Option<String> {
18        if let Some(prefix) = &self.remove_prefix {
19            let (expected_prefix, expected_suffix) = match item_info.kind {
20                ItemKind::Function => ("function_", "_name"),
21                ItemKind::Var => ("var_", "_name"),
22                _ => todo!(),
23            };
24            if let Some(name) = item_info.name.strip_prefix(prefix) {
25                assert!(name.starts_with(expected_prefix));
26                assert!(name.ends_with(expected_suffix));
27                return Some(name.to_string());
28            }
29        }
30        None
31    }
32}
33
34#[derive(Debug)]
35struct EnumVariantRename;
36
37impl ParseCallbacks for EnumVariantRename {
38    fn enum_variant_name(
39        &self,
40        _enum_name: Option<&str>,
41        original_variant_name: &str,
42        _variant_value: EnumVariantValue,
43    ) -> Option<String> {
44        Some(format!("RENAMED_{}", original_variant_name))
45    }
46}
47
48#[derive(Debug)]
49struct BlocklistedTypeImplementsTrait;
50
51impl ParseCallbacks for BlocklistedTypeImplementsTrait {
52    fn blocklisted_type_implements_trait(
53        &self,
54        _name: &str,
55        derive_trait: DeriveTrait,
56    ) -> Option<ImplementsTrait> {
57        if derive_trait == DeriveTrait::Hash {
58            Some(ImplementsTrait::No)
59        } else {
60            Some(ImplementsTrait::Yes)
61        }
62    }
63}
64
65pub fn lookup(cb: &str) -> Box<dyn ParseCallbacks> {
66    match cb {
67        "enum-variant-rename" => Box::new(EnumVariantRename),
68        "blocklisted-type-implements-trait" => {
69            Box::new(BlocklistedTypeImplementsTrait)
70        }
71        call_back => {
72            if call_back.starts_with("remove-function-prefix-") {
73                let prefix = call_back
74                    .split("remove-function-prefix-")
75                    .last()
76                    .to_owned();
77                let lnopc = RemovePrefixParseCallback::new(prefix.unwrap());
78                Box::new(lnopc)
79            } else {
80                panic!("Couldn't find name ParseCallbacks: {}", cb)
81            }
82        }
83    }
84}
85