-
Notifications
You must be signed in to change notification settings - Fork 74
/
Copy pathrust.md
144 lines (103 loc) · 5.31 KB
/
rust.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
date = "2024-02-18T01:01:01Z"
title = "Rust in WebAssembly"
description = "Rust supports a broad array of WebAssembly options."
tags = ["rust", "webassembly"]
template = "page_lang"
[extra]
author = "Fermyon Staff"
url = "https://github.com/fermyon/developer/blob/main/content/wasm-languages/rust.md"
---
Rust is probably the best supported language of the WebAssembly ecosystem.
Not only does Rust support several WebAssembly compile targets,
but `wasmtime`, Spin, Wagi, and many other WebAssembly tools are written in Rust.
Rust can be used to create Fermyon Platform apps.
## Available Implementations
WebAssembly and WASI support are [officially supported](https://www.rust-lang.org/what/wasm) by the Rust project.
## Usage
While the WebAssembly compiler does not ship with the default Rust distribution, it can be easily added.
To add the `wasm32-wasi` compiler, simply use `rustup`:
```console
$ rustup target add wasm32-wasi
```
Then to compile a program to rust, set the target when running `cargo build`:
```console
$ cargo build --target wasm32-wasi --release
```
While `--release` is not required, doing so will drastically reduce the size of the output `.wasm` module.
WebAssembly binaries will be written to your project's `target/wasm32-wasi/release` directory.
## Pros and Cons
Things we like:
- The Rust ecosystem for Wasm and WASI is fabulous
- Many of the Wasm tools are written in Rust, which means there is plenty of code to look at
- Spin usually has Rust support for features before it has support for other languages
- Wasmtime, written in Rust, often has cutting edge features before other runtimes
- We have used many Rust libraries off the shelf with WebAssembly
- Thanks to Cargo's flexible build system, some crates even have special feature flags to enable Wasm features (e.g. Chrono)
- Because of Rust's memory management techniques, Rust binary sizes are small compared to similar languages
Things we're not big fans of:
- Many Rust libraries do not work with Wasm. Most notably, anything that uses Tokio or `async` does not yet work.
## Example
>> All of our examples follow [a documented pattern using common tools](/wasm-languages/about-examples).
Rust can use Spin's native executor as well as Spin's Wagi executor. We strongly recommend the native one, as it has more features.
When writing Spin applications in Rust, use `cargo init --lib` or `cargo new --lib`. Spin loads the `wasm` files as libraries, not as executables with a `main` function.
Here is an example `lib.rs` that uses Spin's native executor:
```rust
use spin_sdk::http::{IntoResponse, Request, Response};
use spin_sdk::http_component;
/// A simple Spin HTTP component.
#[http_component]
fn hello_world(_req: Request) -> anyhow::Result<impl IntoResponse> {
Ok(Response::new(200, "Writing a very simple Spin component in Rust"))
}
```
Note that your `Cargo.toml` will need to include at least the Spin SDK. We recommend starting with something like this:
```toml
[package]
name = "rust-hello"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = [ "cdylib" ]
[dependencies]
# Useful crate to handle errors.
anyhow = "1"
# The Spin SDK.
spin-sdk = "3.0.1"
```
To build a Spin app in rust, use `cargo build`:
```console
$ cargo build --target wasm32-wasi --release
```
(Again, we suggest `--release` to keep binary sizes small.)
The resulting binary can be run in Spin with a `spin.toml` that looks something like this:
```toml
spin_manifest_version = 2
[application]
name = "spin-hello"
version = "1.0.0"
description = "Hello world app."
authors = ["Fermyon Engineering <engineering@fermyon.com>"]
[[trigger.http]]
id = "trigger-hello"
component = "hello"
route = "/"
[component.hello]
source = "target/wasm32-wasi/release/hello.wasm"
[component.hello.build]
command = "cargo build --target wasm32-wasi --release"
```
> Note: we've set the `hello` component's build command to be the `cargo build` invocation above, so that `spin build` will run it from now on.
From there, running the app is as easy as `spin up`!
### Writing Wagi-Based Rust Apps
It is also possible to write a Wagi application in Rust and run it in Spin or Wagi. Examples of this exist [in the Wagi examples repository](https://github.com/deislabs/wagi-examples).
## Learn More
Here are some great resources:
- The official [documentation for Spin](https://developer.fermyon.com/spin/rust-components/) has many examples, including creating Redis listeners.
- Rust has a [dedicated mini-site covering WebAssembly](https://www.rust-lang.org/what/wasm)
- The Rust Linz group did a [presentation on Rust and Wagi](https://www.youtube.com/watch?v=9NDwHBjLlhQ) and posted a GitHub [repo full of Wagi examples](https://github.com/rstropek/rust-samples)
- [Wasmtime](https://wasmtime.dev/) is the reference implementation of Wasm32-WASI.
- [egui](https://www.egui.rs/) provides a GUI toolkit that can be compiled into Wasm and run in the browser
- DeisLabs has some [Rust Wagi examples](https://github.com/deislabs/wagi-examples)
- There are several rich examples in the [Spin Rust SDK repo](https://github.com/fermyon/spin-rust-sdk/tree/stable/examples) as well as the [Spin Up Hub](https://developer.fermyon.com/hub)
- The [Bartholomew CMS](https://github.com/fermyon/bartholomew) is written in Rust and runs in Spin or Wagi
- The [spin-fileserver](https://github.com/fermyon/spin-fileserver) is a simple Rust Spin-native app