1
+ //! Bindings generation support for Rust with the Component Model.
2
+ //!
3
+ //! This crate is a bindings generator for [WIT] and the [Component Model].
4
+ //! Users are likely interested in the [`generate!`] macro which actually
5
+ //! generates bindings. Otherwise this crate provides any runtime support
6
+ //! necessary for the macro-generated code.
7
+ //!
8
+ //! [WIT]: https://component-model.bytecodealliance.org/design/wit.html
9
+ //! [Component Model]: https://component-model.bytecodealliance.org/
10
+
1
11
#![ no_std]
2
12
3
13
extern crate alloc;
@@ -8,8 +18,288 @@ use core::marker;
8
18
use core:: ops:: { Deref , DerefMut } ;
9
19
use core:: sync:: atomic:: { AtomicU32 , Ordering :: Relaxed } ;
10
20
21
+ /// Generate bindings for an input WIT document.
22
+ ///
23
+ /// This macro is the bread-and-butter of the `wit-bindgen` crate. The macro
24
+ /// here will parse [WIT] as input and generate Rust bindings to work with the
25
+ /// `world` that's specified in the [WIT]. For a primer on WIT see [this
26
+ /// documentation][WIT] and for a primer on worlds see [here][worlds].
27
+ ///
28
+ /// [WIT]: https://component-model.bytecodealliance.org/design/wit.html
29
+ /// [worlds]: https://component-model.bytecodealliance.org/design/worlds.html
30
+ ///
31
+ /// This macro takes as input a [WIT package] as well as a [`world`][worlds]
32
+ /// within that package. It will then generate a Rust function for all `import`s
33
+ /// into the world. If there are any `export`s then a Rust `trait` will be
34
+ /// generated for you to implement. The macro additionally takes a number of
35
+ /// configuration parameters documented below as well.
36
+ ///
37
+ /// Basic invocation of the macro can look like:
38
+ ///
39
+ /// ```
40
+ /// use wit_bindgen::generate;
41
+ /// # macro_rules! generate { ($($t:tt)*) => () }
42
+ ///
43
+ /// generate!();
44
+ /// ```
45
+ ///
46
+ /// This will parse a WIT package in the `wit` folder adjacent to your project's
47
+ /// `Cargo.toml` file. Within this WIT package there must be precisely one
48
+ /// `world` and that world will be the one that has bindings generated for it.
49
+ /// All other options remain at their default values (more on this below).
50
+ ///
51
+ /// If your WIT package has more than one `world`, or if you want to select a
52
+ /// world from the dependencies, you can specify a world explicitly:
53
+ ///
54
+ /// ```
55
+ /// use wit_bindgen::generate;
56
+ /// # macro_rules! generate { ($($t:tt)*) => () }
57
+ ///
58
+ /// generate!("my-world");
59
+ /// generate!("wasi:cli/imports");
60
+ /// ```
61
+ ///
62
+ /// This form of the macro takes a single string as an argument which is a
63
+ /// "world specifier" to select which world is being generated. As a single
64
+ /// string, such as `"my-world"`, this selects the world named `my-world` in the
65
+ /// package being parsed in the `wit` folder. The longer form specification
66
+ /// `"wasi:cli/imports"` indicates that the `wasi:cli` package, located in the
67
+ /// `wit/deps` folder, will have a world named `imports` and those bindings will
68
+ /// be generated.
69
+ ///
70
+ /// If your WIT package is located in a different directory than one called
71
+ /// `wit` then it can be specified with the `in` keyword:
72
+ ///
73
+ /// ```
74
+ /// use wit_bindgen::generate;
75
+ /// # macro_rules! generate { ($($t:tt)*) => () }
76
+ ///
77
+ /// generate!(in "./my/other/path/to/wit");
78
+ /// generate!("a-world" in "../path/to/wit");
79
+ /// ```
80
+ ///
81
+ /// The full-form of the macro, however, takes a braced structure which is a
82
+ /// "bag of options":
83
+ ///
84
+ /// ```
85
+ /// use wit_bindgen::generate;
86
+ /// # macro_rules! generate { ($($t:tt)*) => () }
87
+ ///
88
+ /// generate!({
89
+ /// world: "my-world",
90
+ /// path: "../path/to/wit",
91
+ /// // ...
92
+ /// });
93
+ /// ```
94
+ ///
95
+ /// For documentation on each option, see below.
96
+ ///
97
+ /// ## Debugging output to `generate!`
98
+ ///
99
+ /// While `wit-bindgen` is tested to the best of our ability there are
100
+ /// inevitably bugs and issues that arise. These can range from bad error
101
+ /// messages to misconfigured invocations to bugs in the macro itself. To assist
102
+ /// with debugging these situations the macro recognizes an environment
103
+ /// variable:
104
+ ///
105
+ /// ```shell
106
+ /// export WIT_BINDGEN_DEBUG=1
107
+ /// ```
108
+ ///
109
+ /// When set the macro will emit the result of expansion to a file and then
110
+ /// `include!` that file. Any error messages generated by `rustc` should then
111
+ /// point to the generated file and allow you to open it up, read it, and
112
+ /// inspect it. This can often provide better context to the error than rustc
113
+ /// provides by default with macros.
114
+ ///
115
+ /// It is not recommended to set this environment variable by default as it will
116
+ /// cause excessive rebuilds of Cargo projects. It's recommended to only use it
117
+ /// as necessary to debug issues.
118
+ ///
119
+ /// ## Options to `generate!`
120
+ ///
121
+ /// The full list of options that can be passed to the `generate!` macro are as
122
+ /// follows. Note that there are no required options, they all have default
123
+ /// values.
124
+ ///
125
+ ///
126
+ /// ```
127
+ /// use wit_bindgen::generate;
128
+ /// # macro_rules! generate { ($($t:tt)*) => () }
129
+ ///
130
+ /// generate!({
131
+ /// // The name of the world that bindings are being generated for. If this
132
+ /// // is not specified then it's required that the package selected
133
+ /// // below has a single `world` in it.
134
+ /// world: "my-world",
135
+ ///
136
+ /// // Path to parse WIT and its dependencies from. Defaults to the `wit`
137
+ /// // folder adjacent to your `Cargo.toml`.
138
+ /// path: "../path/to/wit",
139
+ ///
140
+ /// // Enables passing "inline WIT". If specified this is the default
141
+ /// // package that a world is selected from. Any dependencies that this
142
+ /// // inline WIT refers to must be defined in the `path` option above.
143
+ /// //
144
+ /// // By default this is not specified.
145
+ /// inline: "
146
+ /// world my-world {
147
+ /// import wasi:cli/imports;
148
+ ///
149
+ /// export my-run: func()
150
+ /// }
151
+ /// ",
152
+ ///
153
+ /// // Additional traits to derive for all defined types. Note that not all
154
+ /// // types may be able to implement these traits, such as resources.
155
+ /// //
156
+ /// // By default this set is empty.
157
+ /// additional_derives: [PartialEq, Eq, Hash, Clone],
158
+ ///
159
+ /// // If the `world` being generated has any exports, then this option is
160
+ /// // required. Each exported interface must have an entry here in addition
161
+ /// // to a `world` key if the world has any top-level exported functions.
162
+ /// //
163
+ /// // Each entry in this map points to a type in Rust. The specified type
164
+ /// // must implement the generated trait.
165
+ /// exports: {
166
+ /// // If the WIT world has top-level function exports, such as:
167
+ /// //
168
+ /// // world my-world {
169
+ /// // export foo: func();
170
+ /// // }
171
+ /// //
172
+ /// // then this option specifies which type implements the world's
173
+ /// // exported functions.
174
+ /// world: MyWorld,
175
+ ///
176
+ /// // For each exported interface from a world a key is additionally
177
+ /// // required. Each key must be a string of the form "a:b/c"
178
+ /// // specifying the "WIT path" to the interface. For example:
179
+ /// //
180
+ /// // package my:package;
181
+ /// //
182
+ /// // interface my-interface {
183
+ /// // foo: func();
184
+ /// // }
185
+ /// //
186
+ /// // world my-world {
187
+ /// // export my-interface;
188
+ /// // export wasi:random/insecure-seed;
189
+ /// // }
190
+ /// //
191
+ /// // this would require these fields to be specified:
192
+ /// "my:package/my-interface": MyInterface,
193
+ /// "wasi:random/insecure-seed": MyInsecureSeed,
194
+ ///
195
+ /// // If an unnamed interface is used then the export's name is the key
196
+ /// // to use:
197
+ /// //
198
+ /// // world my-world {
199
+ /// // export foo: interface {
200
+ /// // some-func: func();
201
+ /// // }
202
+ /// // }
203
+ /// //
204
+ /// // would require:
205
+ /// "foo": MyFoo,
206
+ /// },
207
+ ///
208
+ /// // When generating bindings for imports it might be the case that
209
+ /// // bindings were already generated in a different crate. For example
210
+ /// // if your world refers to WASI types then the `wasi` crate already
211
+ /// // has generated bindings for all WASI types and structures. In this
212
+ /// // situation the key `with` here can be used to use those types
213
+ /// // elsewhere rather than regenerating types.
214
+ /// //
215
+ /// // The `with` key here only works for interfaces referred to by imported
216
+ /// // functions. Additionally it only supports replacing types at the
217
+ /// // interface level at this time.
218
+ /// //
219
+ /// // When an interface is specified here no bindings will be generated at
220
+ /// // all. It's assumed bindings are fully generated upstream. This is an
221
+ /// // indicator that any further references to types defined in these
222
+ /// // interfaces should use the upstream paths specified here instead.
223
+ /// //
224
+ /// // Any unused keys in this map are considered an error.
225
+ /// with: {
226
+ /// "wasi:io/poll": wasi::io::poll,
227
+ /// },
228
+ ///
229
+ /// // An optional list of function names to skip generating bindings for.
230
+ /// // This is only applicable to imports and the name specified is the name
231
+ /// // of the function.
232
+ /// skip: ["foo", "bar", "baz"],
233
+ ///
234
+ /// // Configuration of how Rust types are generated.
235
+ /// //
236
+ /// // This option will change how WIT types are mapped to Rust types. There
237
+ /// // are a number of ways this can be done depending on the context. For
238
+ /// // example a Rust `&str` is suitable to pass to an imported function but
239
+ /// // an exported function receives a `String`. These both represent the
240
+ /// // WIT type `string`, however.
241
+ /// //
242
+ /// // Type generation becomes extra-significant when aggregates come into
243
+ /// // play (such as a WIT `record` or `variant`), especially when the
244
+ /// // aggregate is used both in an imported function and exported one.
245
+ /// //
246
+ /// // There are three modes of ownership, documented here, but only one
247
+ /// // can be specified.
248
+ /// //
249
+ /// // The default mode is "Owning" meaning that all Rust types will by
250
+ /// // default contain their owned containers. For example a `record` with
251
+ /// // a `string` will map to a Rust `struct` containing a `String`. This
252
+ /// // maximizes the chance that types can be shared between imports and
253
+ /// // exports but can come at a cost where calling an import may require
254
+ /// // more allocations than necessary.
255
+ /// ownership: Owning,
256
+ ///
257
+ /// // The second mode of ownership is "Borrowing". This mode then
258
+ /// // additionally has a boolean flag indicating whether duplicate types
259
+ /// // should be generated if necessary.
260
+ /// //
261
+ /// // This mode will prefer using borrowed values in Rust to represent WIT
262
+ /// // values where possible. For example if the argument to an imported
263
+ /// // function is a record-with-a-string then in Rust that will generate a
264
+ /// // `struct` with a lifetime parameter storing `&'a str`.
265
+ /// //
266
+ /// // The `duplicate_if_necessary` flag will cause duplicate types to be
267
+ /// // generated when a WIT type is used both in an import and export. In
268
+ /// // this situation one will be called `FooParam` and one will be called
269
+ /// // `FooResult` (where `foo` is the WIT name).
270
+ /// //
271
+ /// // It's generally recommended to not turn this on unless performance
272
+ /// // requires it. Even if so, please feel free to open an issue on the
273
+ /// // `wit-bindgen` repository to help improve the default "Owning" use
274
+ /// // case above if possible.
275
+ /// ownership: Borrowing { duplicate_if_necessary: false },
276
+ ///
277
+ /// // Configures the path to the `wit-bindgen` crate itself. By default
278
+ /// // this is `wit_bindgen` assuming that your crate depends on the
279
+ /// // `wit-bindgen` crate itself.
280
+ /// runtime_path: "path::to::wit_bindgen",
281
+ ///
282
+ /// // Configure where the `bitflags` crate is located. By default this
283
+ /// // is `wit_bindgen::bitflags` which already reexports `bitflags` for
284
+ /// // you.
285
+ /// bitflags_path: "path::to::bitflags",
286
+ ///
287
+ /// // Indicates that instead of `&str` and `String` the `&[u8]` and
288
+ /// // `Vec<u8>` types should be used. Only intended for cases where
289
+ /// // compiled size is of the utmost concern as this can avoid pulling in
290
+ /// // UTF-8 validation.
291
+ /// raw_strings,
292
+ ///
293
+ /// // Emits `#[cfg(feature = "std")]` around `impl Error for ... {}` blocks
294
+ /// // for generated types. This is a niche option that is only here to
295
+ /// // support the standard library itself depending on this crate one day.
296
+ /// std_feature,
297
+ /// });
298
+ /// ```
299
+ ///
300
+ /// [WIT package]: https://component-model.bytecodealliance.org/design/packages.html
11
301
#[ cfg( feature = "macros" ) ]
12
- pub use wit_bindgen_rust_macro:: * ;
302
+ pub use wit_bindgen_rust_macro:: generate ;
13
303
14
304
// Re-export `bitflags` so that we can reference it from macros.
15
305
#[ doc( hidden) ]
0 commit comments