Skip to content

Commit 4b1ad2f

Browse files
fix(lang/rust): Rust WIT resource instructions (#366)
* fix(lang/rust): Rust WIT resource instructions * refactor: condense crate lib setting instruction to single sentence Co-authored-by: Mikhail Katychev <mkatych@gmail.com> --------- Co-authored-by: Mikhail Katychev <mkatych@gmail.com>
1 parent ac91350 commit 4b1ad2f

1 file changed

Lines changed: 46 additions & 14 deletions

File tree

  • component-model/src/language-support/using-wit-resources

‎component-model/src/language-support/using-wit-resources/rust.md‎

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
## An example stack-based Reverse Polish Notation (RPN) calculator
66

7-
In this section, our example resource will be a [Reverse Polish Notation (RPN)](https://en.wikipedia.org/wiki/Reverse_Polish_notation) calculator. (Engineers of a certain vintage will remember this from handheld calculators of the 1970s.)
7+
In this section, our example resource will be a [Reverse Polish Notation (RPN)](https://en.wikipedia.org/wiki/Reverse_Polish_notation)
8+
calculator. (Engineers of a certain vintage will remember this from handheld calculators of the 1970s.)
89

910
A RPN calculator is a stateful entity: a consumer pushes operands and operations onto a stack
1011
maintained within the calculator, then evaluates the stack to produce a value.
@@ -39,7 +40,19 @@ world calculator {
3940

4041
To implement the calculator in Rust:
4142

42-
1. Create a library component as shown in previous sections, with the WIT given above.
43+
1. [Create a library component](../building-a-simple-component/rust.md), save the
44+
WIT above as `wit/world.wit`, and add `wit-bindgen`:
45+
46+
```sh
47+
cargo add wit-bindgen
48+
```
49+
50+
Be sure to include the `cdylib` crate type in the `Cargo.toml` as well:
51+
52+
```toml
53+
[lib]
54+
crate-type = ["cdylib"]
55+
```
4356

4457
2. Define a Rust `struct` to represent the calculator state:
4558

@@ -57,9 +70,7 @@ To implement the calculator in Rust:
5770

5871
```rust
5972
mod bindings {
60-
use super::Component;
6173
wit_bindgen::generate!();
62-
export!(Component);
6374
}
6475
6576
use bindings::exports::docs::rpn::types::{Guest, GuestEngine, Operation};
@@ -97,14 +108,13 @@ To implement the calculator in Rust:
97108
4. We now have a working calculator type which implements the `engine` contract, but we must still connect that type to the `engine` resource type. This is done by implementing the generated `Guest` trait. For this WIT, the `Guest` trait contains nothing except an associated type. You can use an empty `struct` to implement the `Guest` trait on. Set the associated type for the resource - in our case, `Engine` - to the type which implements the resource trait - in our case, the `CalcEngine` `struct` which implements `GuestEngine`. Then use the `export!` macro to export the mapping:
98109

99110
```rust
100-
// ... bindings & CalcEngine impl code ...
101-
102111
struct Component;
103112
104113
impl Guest for Component {
105114
type Engine = CalcEngine;
106115
}
107116
117+
bindings::export!(Component);
108118
```
109119

110120
This completes the implementation of the calculator `engine` resource. Run `cargo build --target=wasm32-wasip2` to create a component `.wasm` file.
@@ -139,7 +149,7 @@ To use the calculator engine in another component, that component must import th
139149
```rust
140150
mod bindings {
141151
wit_bindgen::generate!({
142-
generate_all
152+
generate_all,
143153
});
144154
}
145155
@@ -160,7 +170,7 @@ Building the component as is creates a WebAssembly component with an *unsatisfie
160170
After building the component, it must be [composed with a `.wasm` component that implements the resource.](../../composing-and-distributing/composing.md). After composition creates a component with no unsatisfied imports, the composed command component can be run with `wasmtime run`.
161171
162172
Alternatively, a host that can provide the `docs:rpn/types` import (and related resource) can also be used to run the component
163-
in it's "incomplete" state (as the host will "complete" the component by providing the expected import).
173+
in its "incomplete" state (as the host will "complete" the component by providing the expected import).
164174
165175
## Implementing and exporting a resource implementation in a host
166176
@@ -200,8 +210,20 @@ to the Wasmtime runtime; other runtimes may express things differently.
200210
201211
```rust
202212
impl docs::rpn::types::HostEngine for MyHost {
203-
fn new(&mut self) -> wasmtime::component::Resource<docs::rpn::types::Engine> { /* ... */ }
204-
fn push_operand(&mut self, self_: wasmtime::component::Resource<docs::rpn::types::Engine>) { /* ... */ }
213+
fn new(
214+
&mut self,
215+
) -> wasmtime::Result<wasmtime::component::Resource<docs::rpn::types::Engine>> {
216+
/* ... */
217+
}
218+
219+
fn push_operand(
220+
&mut self,
221+
self_: wasmtime::component::Resource<docs::rpn::types::Engine>,
222+
operand: u32,
223+
) -> wasmtime::Result<()> {
224+
/* ... */
225+
}
226+
205227
// etc.
206228
}
207229
```
@@ -220,13 +242,23 @@ to the Wasmtime runtime; other runtimes may express things differently.
220242
221243
```rust
222244
impl docs::rpn::types::HostEngine for MyHost {
223-
fn new(&mut self) -> wasmtime::component::Resource<docs::rpn::types::Engine> {
224-
self.calcs.push(CalcEngine::new()).unwrap() // TODO: error handling
245+
fn new(
246+
&mut self,
247+
) -> wasmtime::Result<wasmtime::component::Resource<docs::rpn::types::Engine>> {
248+
self.calcs.push(CalcEngine::new())
225249
}
226-
fn push_operand(&mut self, self_: wasmtime::component::Resource<docs::rpn::types::Engine>) {
227-
let calc_engine = self.calcs.get(&self_).unwrap();
250+
251+
fn push_operand(
252+
&mut self,
253+
self_: wasmtime::component::Resource<docs::rpn::types::Engine>,
254+
operand: u32,
255+
) -> wasmtime::Result<()> {
256+
let calc_engine = self.calcs.get(&self_)?;
228257
// calc_engine is a CalcEngine - call its functions
258+
calc_engine.push_operand(operand);
259+
Ok(())
229260
}
261+
230262
// etc.
231263
}
232264
```

0 commit comments

Comments
 (0)