1 use bindgen::callbacks::*;
2 use bindgen::FieldVisibilityKind;
3
4 #[derive(Debug)]
5 pub struct RemovePrefixParseCallback {
6 pub remove_prefix: Option<String>,
7 }
8
9 impl RemovePrefixParseCallback {
new(prefix: &str) -> Self10 pub fn new(prefix: &str) -> Self {
11 RemovePrefixParseCallback {
12 remove_prefix: Some(prefix.to_string()),
13 }
14 }
15 }
16
17 impl ParseCallbacks for RemovePrefixParseCallback {
generated_name_override(&self, item_info: ItemInfo) -> Option<String>18 fn generated_name_override(&self, item_info: ItemInfo) -> Option<String> {
19 if let Some(prefix) = &self.remove_prefix {
20 let (expected_prefix, expected_suffix) = match item_info.kind {
21 ItemKind::Function => ("function_", "_name"),
22 ItemKind::Var => ("var_", "_name"),
23 _ => todo!(),
24 };
25 if let Some(name) = item_info.name.strip_prefix(prefix) {
26 assert!(name.starts_with(expected_prefix));
27 assert!(name.ends_with(expected_suffix));
28 return Some(name.to_string());
29 }
30 }
31 None
32 }
33 }
34
35 #[derive(Debug)]
36 pub struct PrefixLinkNameParseCallback {
37 pub prefix: Option<String>,
38 }
39
40 impl PrefixLinkNameParseCallback {
new(prefix: &str) -> Self41 pub fn new(prefix: &str) -> Self {
42 PrefixLinkNameParseCallback {
43 prefix: Some(prefix.to_string()),
44 }
45 }
46 }
47
48 impl ParseCallbacks for PrefixLinkNameParseCallback {
generated_link_name_override( &self, item_info: ItemInfo, ) -> Option<String>49 fn generated_link_name_override(
50 &self,
51 item_info: ItemInfo,
52 ) -> Option<String> {
53 self.prefix
54 .as_deref()
55 .map(|prefix| format!("{}{}", prefix, item_info.name))
56 }
57 }
58
59 #[derive(Debug)]
60 struct EnumVariantRename;
61
62 impl ParseCallbacks for EnumVariantRename {
enum_variant_name( &self, _enum_name: Option<&str>, original_variant_name: &str, _variant_value: EnumVariantValue, ) -> Option<String>63 fn enum_variant_name(
64 &self,
65 _enum_name: Option<&str>,
66 original_variant_name: &str,
67 _variant_value: EnumVariantValue,
68 ) -> Option<String> {
69 Some(format!("RENAMED_{}", original_variant_name))
70 }
71 }
72
73 #[derive(Debug)]
74 struct BlocklistedTypeImplementsTrait;
75
76 impl ParseCallbacks for BlocklistedTypeImplementsTrait {
blocklisted_type_implements_trait( &self, _name: &str, derive_trait: DeriveTrait, ) -> Option<ImplementsTrait>77 fn blocklisted_type_implements_trait(
78 &self,
79 _name: &str,
80 derive_trait: DeriveTrait,
81 ) -> Option<ImplementsTrait> {
82 if derive_trait == DeriveTrait::Hash {
83 Some(ImplementsTrait::No)
84 } else {
85 Some(ImplementsTrait::Yes)
86 }
87 }
88 }
89
90 #[derive(Debug)]
91 struct FieldVisibility {
92 default: FieldVisibilityKind,
93 }
94
95 /// Implements the `field_visibility` function of the trait by checking if the
96 /// field name starts with `private_`. If it does it makes it private, if it
97 /// doesn't it makes it public, taking into account the default visibility.
98 impl ParseCallbacks for FieldVisibility {
99 fn field_visibility(
100 &self,
101 FieldInfo { field_name, .. }: FieldInfo,
102 ) -> Option<FieldVisibilityKind> {
103 match (self.default, field_name.starts_with("private_")) {
104 (FieldVisibilityKind::Private, false) => {
105 Some(FieldVisibilityKind::Public)
106 }
107 (FieldVisibilityKind::Public, true) => {
108 Some(FieldVisibilityKind::Private)
109 }
110 (FieldVisibilityKind::PublicCrate, _) => unimplemented!(),
111 _ => None,
112 }
113 }
114 }
115
116 #[derive(Debug)]
117 pub(super) struct WrapAsVariadicFn;
118
119 impl ParseCallbacks for WrapAsVariadicFn {
wrap_as_variadic_fn(&self, name: &str) -> Option<String>120 fn wrap_as_variadic_fn(&self, name: &str) -> Option<String> {
121 Some(name.to_owned() + "_wrapped")
122 }
123 }
124
lookup(cb: &str) -> Box<dyn ParseCallbacks>125 pub fn lookup(cb: &str) -> Box<dyn ParseCallbacks> {
126 match cb {
127 "enum-variant-rename" => Box::new(EnumVariantRename),
128 "blocklisted-type-implements-trait" => {
129 Box::new(BlocklistedTypeImplementsTrait)
130 }
131 "wrap-as-variadic-fn" => Box::new(WrapAsVariadicFn),
132 call_back => {
133 if let Some(prefix) =
134 call_back.strip_prefix("remove-function-prefix-")
135 {
136 let lnopc = RemovePrefixParseCallback::new(prefix);
137 Box::new(lnopc)
138 } else if let Some(prefix) =
139 call_back.strip_prefix("prefix-link-name-")
140 {
141 let plnpc = PrefixLinkNameParseCallback::new(prefix);
142 Box::new(plnpc)
143 } else if let Some(default) =
144 call_back.strip_prefix("field-visibility-default-")
145 {
146 Box::new(FieldVisibility {
147 default: default.parse().expect(
148 "unable to parse field-visibility-default callback",
149 ),
150 })
151 } else {
152 panic!("Couldn't find name ParseCallbacks: {}", cb)
153 }
154 }
155 }
156 }
157