Skip to content

Commit eb15c5e

Browse files
vados-cosmonickate-goldenring
authored andcommitted
fix(lang/rust): link to old WIT, prose & interface use example
Signed-off-by: Victor Adossi <[email protected]>
1 parent ff815db commit eb15c5e

File tree

1 file changed

+44
-10
lines changed
  • component-model/src/language-support

1 file changed

+44
-10
lines changed

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

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@ cargo install cargo-component
1717
1818
## 2. Scaffold a Component with `cargo component`
1919

20-
Create a Rust library that implements the `add` function in the [`adder`world][adder-wit].
20+
Create a Rust library that implements the `add` function in the [`adder` world][adder-wit].
2121

2222
First scaffold a project:
2323

2424
```sh
25-
$ cargo component new add --lib && cd add
25+
$ cargo component new adder --lib && cd adder
2626
```
2727

2828
Note that `cargo component` generates the necessary bindings as a module called `bindings`.
2929

3030
## 3. Add the WIT world the Component will implement
3131

32-
Next, update `wit/world.wit` to match `add.wit`:
32+
Next, update `wit/world.wit` to match the [`adder` world][adder-wit]:
3333

3434
```
3535
package docs:[email protected];
@@ -124,37 +124,71 @@ $ cargo run --release -- 1 2 ../add/target/wasm32-wasip1/release/add.wasm
124124

125125
## Exporting an interface with `cargo component`
126126

127-
The [sample `add.wit` file](https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/example-host/add.wit) exports a function. However, you'll often prefer to export an interface, either to comply with an existing specification or to capture a set of functions and types that tend to go together. For example, to implement the following world:
127+
While it is possible to export a raw function, prefer exporting an interface, similar to the [sample `adder` world][add-wit].
128+
This often makes it easier to comply with an existing specification or to capture a set of functions and types
129+
that tend to go together.
130+
131+
For example, consider the following changes to the `add` interface in the `adder` world:
128132

129133
```wit
130134
package docs:[email protected];
131135
136+
132137
interface add {
133-
add: func(x: u32, y: u32) -> u32;
138+
variant operand {
139+
unsigned32(u32)
140+
signed32(s32)
141+
zero,
142+
}
143+
144+
add: func(x: operand, y: operand) -> result<operand, string>;
134145
}
135146
136147
world adder {
137148
export add;
138149
}
139150
```
140151

141-
you would write the following Rust code:
152+
This would be implemented with the following Rust code:
142153

143154
```rust
155+
#[allow(warnings)]
144156
mod bindings;
145157

146-
// Separating out the interface puts it in a sub-module
147-
use bindings::exports::docs::adder::add::Guest;
158+
use bindings::exports::docs::adder::add::{Guest, Operand};
148159

149160
struct Component;
150161

151162
impl Guest for Component {
152-
fn add(x: u32, y: u32) -> u32 {
153-
x + y
163+
fn add(x: Operand, y: Operand) -> Result<Operand, String> {
164+
let x = convert_operand(x);
165+
let y = convert_operand(y);
166+
match x + y {
167+
v if v == 0 => Ok(Operand::Zero),
168+
v if v < 0 => i32::try_from(v)
169+
.map_err(|e| format!("unexpectedly invalid u32: {e}"))
170+
.map(Operand::Signed32),
171+
v => u32::try_from(v)
172+
.map_err(|e| format!("unexpectedly invalid u32: {e}"))
173+
.map(Operand::Unsigned32),
174+
}
175+
}
176+
}
177+
178+
fn convert_operand(operand: Operand) -> i64 {
179+
match operand {
180+
Operand::Unsigned32(v) => v as i64,
181+
Operand::Signed32(v) => v as i64,
182+
Operand::Zero => 0,
154183
}
155184
}
185+
186+
bindings::export!(Component with_types_in bindings);
156187
```
157188

189+
While the code above is unlikely to appear in real interfaces, but it shows the more common case of an interface
190+
including types that are meant to be used *with* the interface in question.
191+
158192
## Importing an interface with `cargo component`
159193

160194
The world file (`wit/world.wit`) generated for you by `cargo component new --lib` doesn't specify any imports.

0 commit comments

Comments
 (0)