bindgen/
callbacks.rs

1//! A public API for more fine-grained customization of bindgen behavior.
2
3pub use crate::ir::analysis::DeriveTrait;
4pub use crate::ir::derive::CanDerive as ImplementsTrait;
5pub use crate::ir::enum_ty::{EnumVariantCustomBehavior, EnumVariantValue};
6pub use crate::ir::int::IntKind;
7use std::fmt;
8
9/// An enum to allow ignoring parsing of macros.
10#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
11pub enum MacroParsingBehavior {
12    /// Ignore the macro, generating no code for it, or anything that depends on
13    /// it.
14    Ignore,
15    /// The default behavior bindgen would have otherwise.
16    #[default]
17    Default,
18}
19
20/// A trait to allow configuring different kinds of types in different
21/// situations.
22pub trait ParseCallbacks: fmt::Debug {
23    #[cfg(feature = "__cli")]
24    #[doc(hidden)]
25    fn cli_args(&self) -> Vec<String> {
26        vec![]
27    }
28
29    /// This function will be run on every macro that is identified.
30    fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior {
31        MacroParsingBehavior::Default
32    }
33
34    /// This function will run for every extern variable and function. The returned value determines
35    /// the name visible in the bindings.
36    fn generated_name_override(
37        &self,
38        _item_info: ItemInfo<'_>,
39    ) -> Option<String> {
40        None
41    }
42
43    /// This function will run for every extern variable and function. The returned value determines
44    /// the link name in the bindings.
45    fn generated_link_name_override(
46        &self,
47        _item_info: ItemInfo<'_>,
48    ) -> Option<String> {
49        None
50    }
51
52    /// The integer kind an integer macro should have, given a name and the
53    /// value of that macro, or `None` if you want the default to be chosen.
54    fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {
55        None
56    }
57
58    /// This will be run on every string macro. The callback cannot influence the further
59    /// treatment of the macro, but may use the value to generate additional code or configuration.
60    fn str_macro(&self, _name: &str, _value: &[u8]) {}
61
62    /// This will be run on every function-like macro. The callback cannot
63    /// influence the further treatment of the macro, but may use the value to
64    /// generate additional code or configuration.
65    ///
66    /// The first parameter represents the name and argument list (including the
67    /// parentheses) of the function-like macro. The second parameter represents
68    /// the expansion of the macro as a sequence of tokens.
69    fn func_macro(&self, _name: &str, _value: &[&[u8]]) {}
70
71    /// This function should return whether, given an enum variant
72    /// name, and value, this enum variant will forcibly be a constant.
73    fn enum_variant_behavior(
74        &self,
75        _enum_name: Option<&str>,
76        _original_variant_name: &str,
77        _variant_value: EnumVariantValue,
78    ) -> Option<EnumVariantCustomBehavior> {
79        None
80    }
81
82    /// Allows to rename an enum variant, replacing `_original_variant_name`.
83    fn enum_variant_name(
84        &self,
85        _enum_name: Option<&str>,
86        _original_variant_name: &str,
87        _variant_value: EnumVariantValue,
88    ) -> Option<String> {
89        None
90    }
91
92    /// Allows to rename an item, replacing `_original_item_name`.
93    fn item_name(&self, _original_item_name: &str) -> Option<String> {
94        None
95    }
96
97    /// This will be called on every header filename passed to (`Builder::header`)[`crate::Builder::header`].
98    fn header_file(&self, _filename: &str) {}
99
100    /// This will be called on every file inclusion, with the full path of the included file.
101    fn include_file(&self, _filename: &str) {}
102
103    /// This will be called every time `bindgen` reads an environment variable whether it has any
104    /// content or not.
105    fn read_env_var(&self, _key: &str) {}
106
107    /// This will be called to determine whether a particular blocklisted type
108    /// implements a trait or not. This will be used to implement traits on
109    /// other types containing the blocklisted type.
110    ///
111    /// * `None`: use the default behavior
112    /// * `Some(ImplementsTrait::Yes)`: `_name` implements `_derive_trait`
113    /// * `Some(ImplementsTrait::Manually)`: any type including `_name` can't
114    ///   derive `_derive_trait` but can implemented it manually
115    /// * `Some(ImplementsTrait::No)`: `_name` doesn't implement `_derive_trait`
116    fn blocklisted_type_implements_trait(
117        &self,
118        _name: &str,
119        _derive_trait: DeriveTrait,
120    ) -> Option<ImplementsTrait> {
121        None
122    }
123
124    /// Provide a list of custom derive attributes.
125    ///
126    /// If no additional attributes are wanted, this function should return an
127    /// empty `Vec`.
128    fn add_derives(&self, _info: &DeriveInfo<'_>) -> Vec<String> {
129        vec![]
130    }
131
132    /// Provide a list of custom attributes.
133    ///
134    /// If no additional attributes are wanted, this function should return an
135    /// empty `Vec`.
136    fn add_attributes(&self, _info: &AttributeInfo<'_>) -> Vec<String> {
137        vec![]
138    }
139
140    /// Process a source code comment.
141    fn process_comment(&self, _comment: &str) -> Option<String> {
142        None
143    }
144
145    /// Potentially override the visibility of a composite type field.
146    ///
147    /// Caution: This allows overriding standard C++ visibility inferred by
148    /// `respect_cxx_access_specs`.
149    fn field_visibility(
150        &self,
151        _info: FieldInfo<'_>,
152    ) -> Option<crate::FieldVisibilityKind> {
153        None
154    }
155
156    /// Process a function name that as exactly one `va_list` argument
157    /// to be wrapped as a variadic function with the wrapped static function
158    /// feature.
159    ///
160    /// The returned string is new function name.
161    #[cfg(feature = "experimental")]
162    fn wrap_as_variadic_fn(&self, _name: &str) -> Option<String> {
163        None
164    }
165
166    /// This will get called everytime an item (currently struct, union, and alias) is found with some information about it
167    fn new_item_found(&self, _id: DiscoveredItemId, _item: DiscoveredItem) {}
168
169    // TODO add callback for ResolvedTypeRef
170}
171
172/// An identifier for a discovered item. Used to identify an aliased type (see [`DiscoveredItem::Alias`])
173#[derive(Ord, PartialOrd, PartialEq, Eq, Hash, Debug, Clone, Copy)]
174pub struct DiscoveredItemId(usize);
175
176impl DiscoveredItemId {
177    /// Constructor
178    pub fn new(value: usize) -> Self {
179        Self(value)
180    }
181}
182
183/// Struct passed to [`ParseCallbacks::new_item_found`] containing information about discovered
184/// items (struct, union, and alias)
185#[derive(Debug, Hash, Clone, Ord, PartialOrd, Eq, PartialEq)]
186pub enum DiscoveredItem {
187    /// Represents a struct with its original name in C and its generated binding name
188    Struct {
189        /// The original name (learnt from C) of the structure
190        /// Can be None if the union is anonymous.
191        original_name: Option<String>,
192
193        /// The name of the generated binding
194        final_name: String,
195    },
196
197    /// Represents a union with its original name in C and its generated binding name
198    Union {
199        /// The original name (learnt from C) of the structure.
200        /// Can be None if the union is anonymous.
201        original_name: Option<String>,
202
203        /// The name of the generated binding
204        final_name: String,
205    },
206
207    /// Represents an alias like a typedef
208    /// ```c
209    ///     typedef struct MyStruct {
210    ///         ...
211    ///     } StructAlias;
212    /// ```
213    /// Here, the name of the alias is `StructAlias` and it's an alias for `MyStruct`
214    Alias {
215        /// The name of the alias in C (`StructAlias`)
216        alias_name: String,
217
218        /// The identifier of the discovered type
219        alias_for: DiscoveredItemId,
220    }, // functions, modules, etc.
221}
222
223/// Relevant information about a type to which new derive attributes will be added using
224/// [`ParseCallbacks::add_derives`].
225#[derive(Debug)]
226#[non_exhaustive]
227pub struct DeriveInfo<'a> {
228    /// The name of the type.
229    pub name: &'a str,
230    /// The kind of the type.
231    pub kind: TypeKind,
232}
233
234/// Relevant information about a type to which new attributes will be added using
235/// [`ParseCallbacks::add_attributes`].
236#[derive(Debug)]
237#[non_exhaustive]
238pub struct AttributeInfo<'a> {
239    /// The name of the type.
240    pub name: &'a str,
241    /// The kind of the type.
242    pub kind: TypeKind,
243}
244
245#[derive(Debug, Clone, Copy, PartialEq, Eq)]
246/// The kind of the current type.
247pub enum TypeKind {
248    /// The type is a Rust `struct`.
249    Struct,
250    /// The type is a Rust `enum`.
251    Enum,
252    /// The type is a Rust `union`.
253    Union,
254}
255
256/// A struct providing information about the item being passed to [`ParseCallbacks::generated_name_override`].
257#[non_exhaustive]
258pub struct ItemInfo<'a> {
259    /// The name of the item
260    pub name: &'a str,
261    /// The kind of item
262    pub kind: ItemKind,
263}
264
265/// An enum indicating the kind of item for an `ItemInfo`.
266#[non_exhaustive]
267pub enum ItemKind {
268    /// A Function
269    Function,
270    /// A Variable
271    Var,
272}
273
274/// Relevant information about a field for which visibility can be determined using
275/// [`ParseCallbacks::field_visibility`].
276#[derive(Debug)]
277#[non_exhaustive]
278pub struct FieldInfo<'a> {
279    /// The name of the type.
280    pub type_name: &'a str,
281    /// The name of the field.
282    pub field_name: &'a str,
283    /// The name of the type of the field.
284    pub field_type_name: Option<&'a str>,
285}