1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
//! Configure how `cheadergen` generates C/C++ headers from Rust.
//!
//! `cheadergen` generates C/C++ header files from Rust libraries that expose a
//! `pub extern "C"` API. Output is controlled in two complementary ways:
//!
//! - **[`cheadergen.toml`](config_reference)** — a project-wide TOML file that
//! the CLI loads via `--config`. It sets the preamble, include guards, sort
//! order, per-package opaque/skip rules, per-header overrides, and
//! language-specific options. See the [config reference](config_reference)
//! for the full schema.
//! - **Per-item attributes** — `#[cheadergen::config(...)]` on items and
//! `#[cheadergen(...)]` on fields and variants, placed in your Rust source
//! to control how an individual definition appears in the generated header.
//! See the [`config`] macro for the directive reference.
//!
//! # Per-item attributes
//!
//! There are two attribute levels:
//!
//! - [`#[cheadergen::config(...)]`](config) — placed on items (structs, enums,
//! unions, functions, statics, type aliases) to control their header
//! representation.
//! - `#[cheadergen(...)]` — placed on fields and enum variants to control
//! their individual representation within a parent item.
//!
//! ## Example
//!
//! ```ignore
//! #[cheadergen::config(export, rename = "CColor")]
//! #[repr(C)]
//! pub enum Color {
//! #[cheadergen(rename = "COLOR_RED")]
//! Red,
//! Green,
//! Blue,
//! }
//!
//! #[cheadergen::config(export, field_names(x, y))]
//! #[repr(C)]
//! pub struct Point2D(pub f64, pub f64);
//!
//! #[cheadergen::config(skip)]
//! #[unsafe(no_mangle)]
//! pub extern "C" fn internal_helper() {}
//! ```
/// Control how a Rust item appears in the generated C/C++ header.
///
/// # Example
///
/// ```ignore
/// #[cheadergen::config(export, rename = "CConfig")]
/// // ~~~~~~ ~~~~~~~~~~~~~~~~~~
/// // │ └ Override the C name
/// // └ Force inclusion in the header
/// #[repr(C)]
/// pub struct Config {
/// #[cheadergen(rename = "raw_width")]
/// // ~~~~~~~~~~~~~~~~~~~~
/// // └ Override the C field name
/// pub width: u32,
/// #[cheadergen(bitfield = 8)]
/// // ~~~~~~~~~~~
/// // └ Emit as a C bitfield with width 8
/// pub flags: u8,
/// }
/// ```
///
/// # Directives
///
/// | Name | Applies to | Required |
/// |------|-----------|----------|
/// | [`export`](#export) | struct, enum, union, type alias | No |
/// | [`skip`](#skip) | struct, enum, union, type alias, function, static | No |
/// | [`rename`](#rename) | struct, enum, union, type alias, function, static | No |
/// | [`prefix_with_name`](#prefix_with_name) | enum | No |
/// | [`field_names`](#field_names) | tuple struct | No |
/// | [`rename_all`](#rename_all) | struct, enum, union | No |
/// | [`rename_all_fields`](#rename_all_fields) | enum (with struct variant) | No |
///
/// ## `export`
///
/// Force the item to be included in the generated header. By default, `cheadergen` only includes
/// items that are reachable from `pub extern "C"` functions. Use `export` to include items that
/// are not directly reachable but should still appear in the header.
///
/// ```ignore
/// #[cheadergen::config(export)]
/// // ~~~~~~
/// // └ Include this struct in the header
/// #[repr(C)]
/// pub struct Config {
/// pub width: u32,
/// }
/// ```
///
/// Pass `opaque` to emit the type as a forward declaration without exposing its layout:
///
/// ```ignore
/// #[cheadergen::config(export(opaque))]
/// // ~~~~~~~~~~~~~~
/// // └ Include as an opaque (forward-declared) type
/// pub struct OpaqueHandle {
/// _inner: u64,
/// }
/// ```
///
/// Cannot be applied to functions or statics (they are included via `#[unsafe(no_mangle)]`).
/// Cannot be combined with [`skip`](#skip).
///
/// ## `skip`
///
/// Exclude the item from the generated header, even if it would otherwise be included.
///
/// ```ignore
/// #[cheadergen::config(skip)]
/// // ~~~~
/// // └ Exclude this function from the header
/// #[unsafe(no_mangle)]
/// pub extern "C" fn internal_helper() {}
/// ```
///
/// Cannot be combined with [`export`](#export).
///
/// ## `rename`
///
/// Override the C name of the item. By default, the Rust identifier is used as-is.
///
/// ```ignore
/// #[cheadergen::config(rename = "CPoint")]
/// // ~~~~~~~~~~~~~~~~~
/// // └ Use "CPoint" instead of "Point" in the header
/// #[repr(C)]
/// pub struct Point {
/// pub x: f64,
/// pub y: f64,
/// }
/// ```
///
/// ## `prefix_with_name`
///
/// Prefix each variant of a C enum with the enum's name, separated by an underscore.
/// This is common in C to avoid name collisions since C enums share a global namespace.
///
/// ```ignore
/// #[cheadergen::config(prefix_with_name)]
/// // ~~~~~~~~~~~~~~~~
/// // └ Variants become Status_Ok, Status_Error, ...
/// #[repr(C)]
/// pub enum Status {
/// Ok,
/// Error,
/// }
/// ```
///
/// Use `prefix_with_name = false` to explicitly disable the behavior (useful when overriding
/// a default configuration).
///
/// Can only be applied to enums.
///
/// ## `field_names`
///
/// Assign C field names to the fields of a tuple struct. The number of names must match
/// the number of fields.
///
/// ```ignore
/// #[cheadergen::config(field_names(x, y))]
/// // ~~~~~~~~~~~~~~~~~
/// // └ Name the two fields "x" and "y" in the C header
/// #[repr(C)]
/// pub struct Point2D(pub f64, pub f64);
/// ```
///
/// Can only be applied to tuple structs.
///
/// ## `rename_all`
///
/// Bulk-rename fields (struct/union) or variants (enum) using a casing rule. Mirrors serde's
/// directive of the same name. Accepted values (string literal, case-sensitive):
///
/// | Rule | Example: `max_value` / `MaxValue` becomes |
/// |---------------------------|--------------------------------------------|
/// | `"camelCase"` | `maxValue` |
/// | `"PascalCase"` | `MaxValue` |
/// | `"snake_case"` | `max_value` |
/// | `"SCREAMING_SNAKE_CASE"` | `MAX_VALUE` |
///
/// ```ignore
/// #[cheadergen::config(export, rename_all = "camelCase")]
/// // ~~~~~~~~~~~~~~~~~~~~~~~~
/// // └ Fields become maxValue, minValue
/// #[repr(C)]
/// pub struct Settings {
/// pub max_value: u32,
/// pub min_value: u32,
/// }
/// ```
///
/// A per-field/per-variant `#[cheadergen(rename = "...")]` always wins over the bulk rule.
///
/// When combined with [`prefix_with_name`](#prefix_with_name), the prefix (derived from the
/// enum name) is also cased so the resulting C identifier is consistent:
///
/// ```ignore
/// #[cheadergen::config(export, prefix_with_name, rename_all = "SCREAMING_SNAKE_CASE")]
/// #[repr(C)]
/// pub enum MyStatus {
/// OkResult,
/// ErrorCode,
/// }
/// // Variants emitted as `MY_STATUS_OK_RESULT`, `MY_STATUS_ERROR_CODE`.
/// ```
///
/// An explicit `rename = "..."` on the enum short-circuits the prefix casing — the explicit
/// C name is used verbatim as the prefix.
///
/// Cannot be applied to functions, statics, or type aliases.
///
/// ## `rename_all_fields`
///
/// On an enum, bulk-rename the fields inside every struct variant. Accepts the same casing
/// values as [`rename_all`](#rename_all). Variant names themselves are unaffected (use
/// `rename_all` for those).
///
/// ```ignore
/// #[cheadergen::config(export, rename_all_fields = "camelCase")]
/// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/// // └ Struct-variant fields become camelCase
/// #[repr(C)]
/// pub enum Message {
/// Plain,
/// WithBody {
/// message_text: u32, // -> messageText
/// sender_id: u32, // -> senderId
/// },
/// }
/// ```
///
/// Can only be applied to enums that have at least one struct (named-fields) variant.
///
/// # Field and variant directives
///
/// Fields and enum variants use `#[cheadergen(...)]` (without `::config`).
///
/// | Name | Applies to | Required |
/// |------|-----------|----------|
/// | [`rename`](#field-rename) | field, variant | No |
/// | [`bitfield`](#bitfield) | field (not variant) | No |
///
/// ## `rename` (field) {#field-rename}
///
/// Override the C name of a struct field or enum variant.
///
/// ```ignore
/// #[cheadergen::config(export)]
/// #[repr(C)]
/// pub enum Color {
/// #[cheadergen(rename = "COLOR_RED")]
/// // ~~~~~~~~~~~~~~~~~~~~
/// // └ Use "COLOR_RED" instead of "Red"
/// Red,
/// Green,
/// }
/// ```
///
/// ## `bitfield`
///
/// Emit the field as a C bitfield with the given width in bits.
///
/// ```ignore
/// #[cheadergen::config(export)]
/// #[repr(C)]
/// pub struct Flags {
/// #[cheadergen(bitfield = 4)]
/// // ~~~~~~~~~~~
/// // └ Emit as a 4-bit bitfield
/// pub mode: u8,
/// }
/// ```
///
/// Cannot be applied to enum variants.
pub use config;