Skip to content

Commit 3b2678c

Browse files
authored
rust: Add documentation for generate! (#852)
This commit adds rustdoc documentation for the crate and `generate!` now that it's reaching more of a "done" status. Closes #847
1 parent 7b9dbf9 commit 3b2678c

File tree

1 file changed

+291
-1
lines changed

1 file changed

+291
-1
lines changed

crates/guest-rust/src/lib.rs

Lines changed: 291 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
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+
111
#![no_std]
212

313
extern crate alloc;
@@ -8,8 +18,288 @@ use core::marker;
818
use core::ops::{Deref, DerefMut};
919
use core::sync::atomic::{AtomicU32, Ordering::Relaxed};
1020

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
11301
#[cfg(feature = "macros")]
12-
pub use wit_bindgen_rust_macro::*;
302+
pub use wit_bindgen_rust_macro::generate;
13303

14304
// Re-export `bitflags` so that we can reference it from macros.
15305
#[doc(hidden)]

0 commit comments

Comments
 (0)