Skip to main content

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;
7pub use cexpr::token::Kind as TokenKind;
8pub use cexpr::token::Token;
9use std::fmt;
10
11/// An enum to allow ignoring parsing of macros.
12#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
13pub enum MacroParsingBehavior {
14    /// Ignore the macro, generating no code for it, or anything that depends on
15    /// it.
16    Ignore,
17    /// The default behavior bindgen would have otherwise.
18    #[default]
19    Default,
20}
21
22/// A trait to allow configuring different kinds of types in different
23/// situations.
24pub trait ParseCallbacks: fmt::Debug {
25    #[cfg(feature = "__cli")]
26    #[doc(hidden)]
27    fn cli_args(&self) -> Vec<String> {
28        vec![]
29    }
30
31    /// This function will be run on every macro that is identified.
32    fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior {
33        MacroParsingBehavior::Default
34    }
35
36    /// This function will run for every extern variable and function. The returned value determines
37    /// the name visible in the bindings.
38    fn generated_name_override(
39        &self,
40        _item_info: ItemInfo<'_>,
41    ) -> Option<String> {
42        None
43    }
44
45    /// This function will run for every extern variable and function. The returned value determines
46    /// the link name in the bindings.
47    fn generated_link_name_override(
48        &self,
49        _item_info: ItemInfo<'_>,
50    ) -> Option<String> {
51        None
52    }
53
54    /// Modify the contents of a macro
55    fn modify_macro(&self, _name: &str, _tokens: &mut Vec<Token>) {}
56
57    /// The integer kind an integer macro should have, given a name and the
58    /// value of that macro, or `None` if you want the default to be chosen.
59    fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {
60        None
61    }
62
63    /// This will be run on every string macro. The callback cannot influence the further
64    /// treatment of the macro, but may use the value to generate additional code or configuration.
65    fn str_macro(&self, _name: &str, _value: &[u8]) {}
66
67    /// This will be run on every function-like macro. The callback cannot
68    /// influence the further treatment of the macro, but may use the value to
69    /// generate additional code or configuration.
70    ///
71    /// The first parameter represents the name and argument list (including the
72    /// parentheses) of the function-like macro. The second parameter represents
73    /// the expansion of the macro as a sequence of tokens.
74    fn func_macro(&self, _name: &str, _value: &[&[u8]]) {}
75
76    /// This function should return whether, given an enum variant
77    /// name, and value, this enum variant will forcibly be a constant.
78    fn enum_variant_behavior(
79        &self,
80        _enum_name: Option<&str>,
81        _original_variant_name: &str,
82        _variant_value: EnumVariantValue,
83    ) -> Option<EnumVariantCustomBehavior> {
84        None
85    }
86
87    /// Allows to rename an enum variant, replacing `_original_variant_name`.
88    fn enum_variant_name(
89        &self,
90        _enum_name: Option<&str>,
91        _original_variant_name: &str,
92        _variant_value: EnumVariantValue,
93    ) -> Option<String> {
94        None
95    }
96
97    /// Allows to rename an item, replacing `_item_info.name`.
98    fn item_name(&self, _item_info: ItemInfo) -> Option<String> {
99        None
100    }
101
102    /// This will be called on every header filename passed to [`Builder::header`][crate::Builder::header].
103    fn header_file(&self, _filename: &str) {}
104
105    /// This will be called on every file inclusion, with the full path of the included file.
106    fn include_file(&self, _filename: &str) {}
107
108    /// This will be called every time `bindgen` reads an environment variable whether it has any
109    /// content or not.
110    fn read_env_var(&self, _key: &str) {}
111
112    /// This will be called to determine whether a particular blocklisted type
113    /// implements a trait or not. This will be used to implement traits on
114    /// other types containing the blocklisted type.
115    ///
116    /// * `None`: use the default behavior
117    /// * `Some(ImplementsTrait::Yes)`: `_name` implements `_derive_trait`
118    /// * `Some(ImplementsTrait::Manually)`: any type including `_name` can't
119    ///   derive `_derive_trait` but can implemented it manually
120    /// * `Some(ImplementsTrait::No)`: `_name` doesn't implement `_derive_trait`
121    fn blocklisted_type_implements_trait(
122        &self,
123        _name: &str,
124        _derive_trait: DeriveTrait,
125    ) -> Option<ImplementsTrait> {
126        None
127    }
128
129    /// Provide a list of custom derive attributes.
130    ///
131    /// If no additional attributes are wanted, this function should return an
132    /// empty `Vec`.
133    fn add_derives(&self, _info: &DeriveInfo<'_>) -> Vec<String> {
134        vec![]
135    }
136
137    /// Provide a list of custom attributes.
138    ///
139    /// If no additional attributes are wanted, this function should return an
140    /// empty `Vec`.
141    fn add_attributes(&self, _info: &AttributeInfo<'_>) -> Vec<String> {
142        vec![]
143    }
144
145    /// Provide a list of custom attributes for struct/union fields.
146    ///
147    /// These attributes will be applied to the field in the generated Rust code.
148    /// If no additional attributes are wanted, this function should return an
149    /// empty `Vec`.
150    ///
151    /// # Example
152    ///
153    /// ```
154    /// # use bindgen::callbacks::{ParseCallbacks, FieldAttributeInfo};
155    /// # #[derive(Debug)]
156    /// # struct MyCallbacks;
157    /// # impl ParseCallbacks for MyCallbacks {
158    /// fn field_attributes(&self, info: &FieldAttributeInfo<'_>) -> Vec<String> {
159    ///     if info.field_name == "internal" {
160    ///         vec!["serde(skip)".to_string()]
161    ///     } else if info.field_name == "0" {
162    ///         // Newtype tuple field
163    ///         vec!["serde(transparent)".to_string()]
164    ///     } else {
165    ///         vec![]
166    ///     }
167    /// }
168    /// # }
169    /// ```
170    fn field_attributes(&self, _info: &FieldAttributeInfo<'_>) -> Vec<String> {
171        vec![]
172    }
173
174    /// Process a source code comment.
175    fn process_comment(&self, _comment: &str) -> Option<String> {
176        None
177    }
178
179    /// Potentially override the visibility of a composite type field.
180    ///
181    /// Caution: This allows overriding standard C++ visibility inferred by
182    /// `respect_cxx_access_specs`.
183    fn field_visibility(
184        &self,
185        _info: FieldInfo<'_>,
186    ) -> Option<crate::FieldVisibilityKind> {
187        None
188    }
189
190    /// Process a function name that as exactly one `va_list` argument
191    /// to be wrapped as a variadic function with the wrapped static function
192    /// feature.
193    ///
194    /// The returned string is new function name.
195    #[cfg(feature = "experimental")]
196    fn wrap_as_variadic_fn(&self, _name: &str) -> Option<String> {
197        None
198    }
199
200    /// This will get called everytime an item (currently struct, union, and alias) is found with some information about it
201    fn new_item_found(
202        &self,
203        _id: DiscoveredItemId,
204        _item: DiscoveredItem,
205        _source_location: Option<&SourceLocation>,
206    ) {
207    }
208
209    // TODO add callback for ResolvedTypeRef
210}
211
212/// An identifier for a discovered item. Used to identify an aliased type (see [`DiscoveredItem::Alias`])
213#[derive(Ord, PartialOrd, PartialEq, Eq, Hash, Debug, Clone, Copy)]
214pub struct DiscoveredItemId(usize);
215
216impl DiscoveredItemId {
217    /// Constructor
218    pub fn new(value: usize) -> Self {
219        Self(value)
220    }
221}
222
223/// Struct passed to [`ParseCallbacks::new_item_found`] containing information about discovered
224/// items (struct, union, and alias)
225#[derive(Debug, Hash, Clone, Ord, PartialOrd, Eq, PartialEq)]
226pub enum DiscoveredItem {
227    /// Represents a struct with its original name in C and its generated binding name
228    Struct {
229        /// The original name (learnt from C) of the structure
230        /// Can be None if the union is anonymous.
231        original_name: Option<String>,
232
233        /// The name of the generated binding
234        final_name: String,
235    },
236
237    /// Represents a union with its original name in C and its generated binding name
238    Union {
239        /// The original name (learnt from C) of the structure.
240        /// Can be None if the union is anonymous.
241        original_name: Option<String>,
242
243        /// The name of the generated binding
244        final_name: String,
245    },
246
247    /// Represents an alias like a typedef
248    /// ```c
249    ///     typedef struct MyStruct {
250    ///         ...
251    ///     } StructAlias;
252    /// ```
253    /// Here, the name of the alias is `StructAlias` and it's an alias for `MyStruct`
254    Alias {
255        /// The name of the alias in C (`StructAlias`)
256        alias_name: String,
257
258        /// The identifier of the discovered type
259        alias_for: DiscoveredItemId,
260    },
261
262    /// Represents an enum.
263    Enum {
264        /// The final name of the generated binding
265        final_name: String,
266    },
267
268    /// A function or method.
269    Function {
270        /// The final name used.
271        final_name: String,
272    },
273
274    /// A method.
275    Method {
276        /// The final name used.
277        final_name: String,
278
279        /// Type to which this method belongs.
280        parent: DiscoveredItemId,
281    }, // modules, etc.
282
283    /// A constant.
284    Constant {
285        /// The final name of the generated binding
286        final_name: String,
287    },
288
289    /// A variable.
290    Variable {
291        /// The final name of the generated binding
292        final_name: String,
293    },
294}
295
296/// Relevant information about a type to which new derive attributes will be added using
297/// [`ParseCallbacks::add_derives`].
298#[derive(Debug, Clone, Copy, PartialEq, Eq)]
299#[non_exhaustive]
300pub struct DeriveInfo<'a> {
301    /// The name of the type.
302    pub name: &'a str,
303    /// The kind of the type.
304    pub kind: TypeKind,
305}
306
307/// Relevant information about a type to which new attributes will be added using
308/// [`ParseCallbacks::add_attributes`].
309#[derive(Debug, Clone, Copy, PartialEq, Eq)]
310#[non_exhaustive]
311pub struct AttributeInfo<'a> {
312    /// The name of the type.
313    pub name: &'a str,
314    /// The kind of the type.
315    pub kind: TypeKind,
316}
317
318#[derive(Debug, Clone, Copy, PartialEq, Eq)]
319/// The kind of the current type.
320pub enum TypeKind {
321    /// The type is a Rust `struct`.
322    Struct,
323    /// The type is a Rust `enum`.
324    Enum,
325    /// The type is a Rust `union`.
326    Union,
327}
328
329/// A struct providing information about the item being passed to [`ParseCallbacks::generated_name_override`].
330#[derive(Debug, Clone, Copy, PartialEq, Eq)]
331#[non_exhaustive]
332pub struct ItemInfo<'a> {
333    /// The name of the item
334    pub name: &'a str,
335    /// The kind of item
336    pub kind: ItemKind,
337}
338
339/// An enum indicating the kind of item for an `ItemInfo`.
340#[derive(Debug, Clone, Copy, PartialEq, Eq)]
341#[non_exhaustive]
342pub enum ItemKind {
343    /// A module
344    Module,
345    /// A type
346    Type,
347    /// A Function
348    Function,
349    /// A Variable
350    Var,
351}
352
353/// Relevant information about a field for which visibility can be determined using
354/// [`ParseCallbacks::field_visibility`].
355#[derive(Debug, Clone, Copy, PartialEq, Eq)]
356#[non_exhaustive]
357pub struct FieldInfo<'a> {
358    /// The name of the type.
359    pub type_name: &'a str,
360    /// The name of the field.
361    pub field_name: &'a str,
362    /// The name of the type of the field.
363    pub field_type_name: Option<&'a str>,
364}
365
366/// Relevant information about a field to which new attributes will be added using
367/// [`ParseCallbacks::field_attributes`].
368#[derive(Debug, Clone, Copy, PartialEq, Eq)]
369#[non_exhaustive]
370pub struct FieldAttributeInfo<'a> {
371    /// The name of the containing type (struct/union).
372    pub type_name: &'a str,
373
374    /// The kind of the containing type.
375    pub type_kind: TypeKind,
376
377    /// The name of the field.
378    ///
379    /// For newtype tuple structs (when using `--default-alias-style=new_type`),
380    /// this will be `"0"` for the inner field.
381    pub field_name: &'a str,
382
383    /// The name of the field's type, if available.
384    pub field_type_name: Option<&'a str>,
385}
386
387/// Location in the source code. Roughly equivalent to the same type
388/// within `clang_sys`.
389#[derive(Clone, Debug, PartialEq, Eq)]
390pub struct SourceLocation {
391    /// Line number.
392    pub line: usize,
393    /// Column number within line.
394    pub col: usize,
395    /// Byte offset within file.
396    pub byte_offset: usize,
397    /// Filename, if known.
398    pub file_name: Option<String>,
399}