Skip to content

Commit 246a610

Browse files
refactor(lang/rust): update rust language guide
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
1 parent b0def76 commit 246a610

1 file changed

Lines changed: 64 additions & 17 deletions

File tree

  • component-model/src/language-support

component-model/src/language-support/rust.md

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# Components in Rust
22

3-
Rust has first-class support for the component model via [the `cargo component` tool](https://github.com/bytecodealliance/cargo-component). It is a `cargo` subcommand for
4-
creating WebAssembly components using Rust as the component's implementation language.
3+
Rust has first-class support for the component model via [the `cargo component` tool](https://github.com/bytecodealliance/cargo-component).
54

6-
## Installing `cargo component`
5+
`cargo component` is is a `cargo` subcommand for creating WebAssembly components
6+
using Rust as the component's implementation language.
7+
8+
## 1. Installing `cargo component`
79

810
To install `cargo component`, run:
911

@@ -13,58 +15,101 @@ cargo install cargo-component
1315

1416
> You can find more details about `cargo component` in its [crates.io page](https://crates.io/crates/cargo-component).
1517
16-
## Building a Component with `cargo component`
18+
## 2. Scaffold a Component with `cargo component`
19+
20+
Create a Rust library that implements the `add` function in the [`adder`world][adder-wit].
1721

18-
Create a Rust library that implements the `add` function in the [`example`
19-
world](https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/example-host/add.wit). First scaffold a project:
22+
First scaffold a project:
2023

2124
```sh
2225
$ cargo component new add --lib && cd add
2326
```
2427

25-
Note that `cargo component` generates the necessary bindings as a module called `bindings`.
28+
Note that `cargo component` generates the necessary bindings as a module called `bindings`.
29+
30+
## 3. Add the WIT world the Component will implement
2631

27-
Next, update `wit/world.wit` to match `add.wit` and modify the component package reference to change the
28-
package name to `example:component`. The `component` section of `Cargo.toml` should look like the following:
32+
Next, update `wit/world.wit` to match `add.wit`:
33+
34+
```
35+
package docs:adder@0.1.0;
36+
37+
interface add {
38+
add: func(x: u32, y: u32) -> u32;
39+
}
40+
41+
world adder {
42+
export add;
43+
}
44+
```
45+
46+
The `component` section of `Cargo.toml` should look like the following:
2947

3048
```toml
3149
[package.metadata.component]
32-
package = "example:component"
50+
package = "docs:adder"
3351
```
3452

35-
`cargo component` will generate bindings for the world specified in a package's `Cargo.toml`. In particular, it will create a `Guest` trait that a component should implement. Since our `example` world has no interfaces, the trait lives directly under the bindings module. Implement the `Guest` trait in `add/src/lib.rs` such that it satisfies the `example` world, adding an `add` function:
53+
## 4. Generate bindings for our component
54+
55+
After performing these changes, we can re-generate bindings with `cargo component bindings`:
56+
57+
```console
58+
cargo component bindings
59+
```
60+
61+
`cargo component bindings` will generate bindings for the world specified in a package's `Cargo.toml`. In particular,
62+
`cargo component` will create a `Guest` trait that a component should implement.
63+
64+
## 5. Implement the generated `Guest` trait
65+
66+
Implement the `Guest` trait in `src/lib.rs`, using the scaffolded code. Your code should look something like the following:
3667

3768
```rs
69+
#[allow(warnings)]
70+
mod bindings;
71+
72+
use bindings::exports::docs::adder::add::Guest;
73+
3874
struct Component;
3975

4076
impl Guest for Component {
4177
fn add(x: u32, y: u32) -> u32 {
42-
x + y
78+
return x + y;
4379
}
4480
}
81+
82+
bindings::export!(Component with_types_in bindings);
4583
```
4684

85+
## 6. Build the component
86+
4787
Now, use `cargo component` to build the component, being sure to optimize with a release build.
4888

49-
```sh
50-
$ cargo component build --release
89+
```console
90+
cargo component build --release
5191
```
5292

5393
You can use `wasm-tools component wit` to output the WIT package of the component:
5494

55-
```sh
95+
```
5696
$ wasm-tools component wit target/wasm32-wasip1/release/add.wasm
5797
package root:component;
5898
5999
world root {
60-
export add: func(x: s32, y: s32) -> s32;
100+
export docs:adder/add@0.1.0;
101+
}
102+
package docs:adder@0.1.0 {
103+
interface add {
104+
add: func(x: u32, y: u32) -> u32;
105+
}
61106
}
62107
```
63108

64109
### Running a Component from Rust Applications
65110

66111
To verify that our component works, lets run it from a Rust application that knows how to run a
67-
component targeting the [`example` world](https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/example-host/add.wit).
112+
component targeting the [`adder` world][adder-wit].
68113

69114
The application uses [`wasmtime`](https://github.com/bytecodealliance/wasmtime) crates to generate
70115
Rust bindings, bring in WASI worlds, and execute the component.
@@ -534,3 +579,5 @@ If you are hosting a Wasm runtime, you can export a resource from your host for
534579
// etc.
535580
}
536581
```
582+
583+
[adder-wit]: https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/tutorial/wit/adder/world.wit

0 commit comments

Comments
 (0)