You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: component-model/src/language-support/rust.md
+79-25Lines changed: 79 additions & 25 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -276,9 +276,60 @@ $ wasmtime run ./my-composed-command.wasm
276
276
1 + 1 = 579 # might need to go back and do some work on the calculator implementation
277
277
```
278
278
279
+
## Using user-defined types
280
+
281
+
[User-defined types](../design/wit.md#user-defined-types) map to Rust types as follows.
282
+
283
+
| WIT type | Rust binding |
284
+
|------------|--------------|
285
+
|`record`|`struct` with public fields corresponding to the record fields |
286
+
|`variant`|`enum` with cases corresponding to the variant cases |
287
+
|`enum`|`enum` with cases corresponding to the enum cases, with no data attached |
288
+
|`resource`|[See below](#using-resources)|
289
+
|`flags`| Opaque type supporting bit flag operations, with constants for flag values |
290
+
291
+
For example, consider the following WIT:
292
+
293
+
```wit
294
+
interface types {
295
+
enum operation {
296
+
add,
297
+
sub,
298
+
mul,
299
+
div
300
+
}
301
+
302
+
record expression {
303
+
left: u32,
304
+
operation: operation,
305
+
right: u32
306
+
}
307
+
308
+
eval: func(expr: expression) -> u32;
309
+
}
310
+
```
311
+
312
+
When exported from a component, this could be implemented as:
313
+
314
+
```rust
315
+
implGuestforImplementation {
316
+
fneval(expr:Expression) ->u32 {
317
+
// Record fields become public fields on a struct
318
+
let (l, r) = (expr.left, expr.right);
319
+
matchexpr.operation {
320
+
// Enum becomes an enum with only unit cases
321
+
Operation::Add=>l+r,
322
+
Operation::Sub=>l-r,
323
+
Operation::Mul=>l*r,
324
+
Operation::Div=>l/r,
325
+
}
326
+
}
327
+
}
328
+
```
329
+
279
330
## Using resources
280
331
281
-
[Resources](../design/wit.md#resources) are handles to entities that live outside the component, for example in a host, or in a different component. You can import or export resources via `cargo component`.
332
+
[Resources](../design/wit.md#resources) are handles to entities that live outside the component, for example in a host, or in a different component.
282
333
283
334
### Example
284
335
@@ -288,23 +339,23 @@ In this section, our example resource will be a [Reverse Polish Notation (RPN)](
288
339
package docs:rpn@0.1.0;
289
340
290
341
interface types {
291
-
enum operation {
292
-
add,
293
-
sub,
294
-
mul,
295
-
div
296
-
}
297
-
298
-
resource engine {
299
-
constructor();
300
-
push-operand: func(operand: u32);
301
-
push-operation: func(operation: operation);
302
-
execute: func() -> u32;
303
-
}
342
+
enum operation {
343
+
add,
344
+
sub,
345
+
mul,
346
+
div
347
+
}
348
+
349
+
resource engine {
350
+
constructor();
351
+
push-operand: func(operand: u32);
352
+
push-operation: func(operation: operation);
353
+
execute: func() -> u32;
354
+
}
304
355
}
305
356
306
357
world calculator {
307
-
export types;
358
+
export types;
308
359
}
309
360
```
310
361
@@ -326,9 +377,11 @@ struct CalcEngine {
326
377
327
378
> Why is the stack wrapped in a `RefCell`? As we will see, the generated Rust trait for the calculator engine has _immutable_ references to `self`. But our implementation of that trait will need to mutate the stack. So we need a type that allows for interior mutability, such as `RefCell<T>` or `Arc<RwLock<T>>`.
328
379
329
-
3. The generated bindings for an exported resource include a trait named `GuestX`, where `X` is the resource name. For the calculator `engine` resource, the trait is `GuestEngine`. Implement this trait on the `struct` from step 2:
380
+
3. The generated bindings (`bindings.rs`) for an exported resource include a trait named `GuestX`, where `X` is the resource name. (You may need to run `cargo component build` to regenerate the bindings after updating the WIT.) For the calculator `engine` resource, the trait is `GuestEngine`. Implement this trait on the `struct` from step 2:
0 commit comments