Skip to content

Commit 4c9ff82

Browse files
authored
feat: add binding crate integrations (#89)
* feat(io): implement `Read` and `Write` for streams Signed-off-by: Roman Volosatovs <[email protected]> * feat(rand): add `rand` crate integration Signed-off-by: Roman Volosatovs <[email protected]> * chore: split examples into `std` and `no_std` Signed-off-by: Roman Volosatovs <[email protected]> * ci: build all std and no_std examples Signed-off-by: Roman Volosatovs <[email protected]> * refactor(rand): use `writeln` to write to stdout Signed-off-by: Roman Volosatovs <[email protected]> * feat(wasi-ext): add workspace crate Signed-off-by: Roman Volosatovs <[email protected]> * ci: build in `--workspace` mode Signed-off-by: Roman Volosatovs <[email protected]> --------- Signed-off-by: Roman Volosatovs <[email protected]>
1 parent 13e01d5 commit 4c9ff82

File tree

15 files changed

+290
-19
lines changed

15 files changed

+290
-19
lines changed

.github/workflows/main.yml

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ jobs:
1313
- name: Install Rust
1414
run: rustup update ${{ matrix.rust }} && rustup default ${{ matrix.rust }} && rustup component add rustfmt
1515
- run: rustup target add wasm32-wasi wasm32-unknown-unknown
16-
- run: cargo build
17-
- run: cargo build --no-default-features
18-
- run: cargo build --target wasm32-wasi
19-
- run: cargo build --target wasm32-wasi --no-default-features
20-
- run: cargo test --doc
16+
- run: cargo build --workspace
17+
- run: cargo build --workspace --no-default-features
18+
- run: cargo build --workspace --target wasm32-wasi
19+
- run: cargo build --workspace --target wasm32-wasi --no-default-features
20+
- run: cargo test --workspace --doc
2121
- name: Install Wasmtime
2222
uses: bytecodealliance/actions/wasmtime/setup@v1
2323
with:
@@ -26,16 +26,38 @@ jobs:
2626
uses: bytecodealliance/actions/wasm-tools/setup@v1
2727
with:
2828
version: "1.202.0"
29-
- run: cargo build --examples --target wasm32-wasi
3029
- run: curl -LO https://github.com/bytecodealliance/wasmtime/releases/download/v19.0.0/wasi_snapshot_preview1.command.wasm
30+
31+
- run: cargo build --examples --target wasm32-wasi --no-default-features
32+
33+
- run: wasm-tools component new ./target/wasm32-wasi/debug/examples/hello-world-no_std.wasm --adapt ./wasi_snapshot_preview1.command.wasm -o component.wasm
34+
- run: wasmtime run component.wasm
35+
36+
- run: cargo build --examples --target wasm32-unknown-unknown --no-default-features
37+
38+
- run: wasm-tools component new ./target/wasm32-unknown-unknown/debug/examples/cli_command_no_std.wasm -o component.wasm
39+
- run: wasmtime run component.wasm
40+
41+
- run: wasm-tools component new ./target/wasm32-unknown-unknown/debug/examples/http_proxy_no_std.wasm -o component.wasm
42+
- run: wasm-tools component targets wit component.wasm -w wasi:http/proxy
43+
44+
- run: cargo build --examples --target wasm32-wasi
45+
3146
- run: wasm-tools component new ./target/wasm32-wasi/debug/examples/hello-world.wasm --adapt ./wasi_snapshot_preview1.command.wasm -o component.wasm
3247
- run: wasmtime run component.wasm
48+
3349
- run: cargo build --examples --target wasm32-unknown-unknown
50+
3451
- run: wasm-tools component new ./target/wasm32-unknown-unknown/debug/examples/cli_command.wasm -o component.wasm
3552
- run: wasmtime run component.wasm
53+
3654
- run: wasm-tools component new ./target/wasm32-unknown-unknown/debug/examples/http_proxy.wasm -o component.wasm
3755
- run: wasm-tools component targets wit component.wasm -w wasi:http/proxy
3856

57+
- run: cargo build --examples --workspace --target wasm32-wasi --features rand
58+
59+
- run: wasm-tools component new ./target/wasm32-wasi/debug/examples/rand.wasm --adapt ./wasi_snapshot_preview1.command.wasm -o component.wasm
60+
- run: wasmtime run component.wasm
3961

4062
rustfmt:
4163
name: Rustfmt

Cargo.toml

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,26 @@
22
name = "wasi"
33
version = "0.13.0+wasi-0.2.0"
44
authors = ["The Cranelift Project Developers"]
5-
license = "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT"
65
description = "WASI API bindings for Rust"
7-
edition = "2021"
86
categories = ["no-std", "wasm"]
97
keywords = ["webassembly", "wasm"]
10-
repository = "https://github.com/bytecodealliance/wasi-rs"
118
readme = "README.md"
129
documentation = "https://docs.rs/wasi"
10+
license.workspace = true
11+
edition.workspace = true
12+
repository.workspace = true
13+
14+
[workspace.package]
15+
edition = "2021"
16+
license = "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT"
17+
repository = "https://github.com/bytecodealliance/wasi-rs"
18+
19+
[workspace.dependencies]
20+
rand = { version = "0.8.5", default-features = false }
21+
wasi = { version = "0.13", path = ".", default-features = false }
22+
23+
[workspace]
24+
members = ["./crates/*"]
1325

1426
[dependencies]
1527
wit-bindgen-rt = { version = "0.23.0", features = ["bitflags"] }
@@ -25,10 +37,24 @@ std = []
2537
# Unstable feature to support being a libstd dependency
2638
rustc-dep-of-std = ["compiler_builtins", "core", "rustc-std-workspace-alloc"]
2739

40+
[[example]]
41+
name = "cli-command-no_std"
42+
crate-type = ["cdylib"]
43+
2844
[[example]]
2945
name = "cli-command"
3046
crate-type = ["cdylib"]
47+
required-features = ["std"]
48+
49+
[[example]]
50+
name = "hello-world"
51+
required-features = ["std"]
52+
53+
[[example]]
54+
name = "http-proxy-no_std"
55+
crate-type = ["cdylib"]
3156

3257
[[example]]
3358
name = "http-proxy"
3459
crate-type = ["cdylib"]
60+
required-features = ["std"]

crates/wasi-ext/Cargo.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "wasi-ext"
3+
version = "0.1.0"
4+
authors = ["Roman Volosatovs <[email protected]>"]
5+
description = "Third-party crate integrations for WASI"
6+
7+
license.workspace = true
8+
edition.workspace = true
9+
repository.workspace = true
10+
11+
[features]
12+
default = ["std"]
13+
std = ["wasi/std"]
14+
15+
[dependencies]
16+
rand = { workspace = true, optional = true }
17+
wasi = { workspace = true }
18+
19+
[[example]]
20+
name = "rand"
21+
required-features = ["rand", "std"]

crates/wasi-ext/examples/rand.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use std::io::Write as _;
2+
3+
use wasi_ext::rand::rand::Rng as _;
4+
use wasi_ext::rand::{HostInsecureRng, HostRng};
5+
6+
fn main() {
7+
let mut stdout = wasi::cli::stdout::get_stdout();
8+
9+
let r: u64 = HostRng.gen();
10+
writeln!(stdout, "Cryptographically-secure random u64 is {r}").unwrap();
11+
12+
let r: u64 = HostInsecureRng.gen();
13+
writeln!(stdout, "Pseudo-random u64 is {r}").unwrap();
14+
15+
stdout.flush().unwrap();
16+
}

crates/wasi-ext/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#[cfg(feature = "rand")]
2+
pub mod rand;

crates/wasi-ext/src/rand.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
pub use rand;
2+
3+
use rand::{CryptoRng, RngCore};
4+
5+
/// The secure interface for cryptographically-secure random numbers
6+
pub struct HostRng;
7+
8+
impl CryptoRng for HostRng {}
9+
10+
impl RngCore for HostRng {
11+
#[inline]
12+
fn next_u32(&mut self) -> u32 {
13+
wasi::random::random::get_random_u64() as _
14+
}
15+
16+
#[inline]
17+
fn next_u64(&mut self) -> u64 {
18+
wasi::random::random::get_random_u64()
19+
}
20+
21+
fn fill_bytes(&mut self, dest: &mut [u8]) {
22+
let n = dest.len();
23+
if usize::BITS <= u64::BITS || n <= u64::MAX as _ {
24+
dest.copy_from_slice(&wasi::random::random::get_random_bytes(n as _));
25+
} else {
26+
let (head, tail) = dest.split_at_mut(u64::MAX as _);
27+
head.copy_from_slice(&wasi::random::random::get_random_bytes(u64::MAX));
28+
self.fill_bytes(tail);
29+
}
30+
}
31+
32+
#[inline]
33+
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
34+
self.fill_bytes(dest);
35+
Ok(())
36+
}
37+
}
38+
39+
/// The insecure interface for insecure pseudo-random numbers
40+
pub struct HostInsecureRng;
41+
42+
impl RngCore for HostInsecureRng {
43+
#[inline]
44+
fn next_u32(&mut self) -> u32 {
45+
wasi::random::insecure::get_insecure_random_u64() as _
46+
}
47+
48+
#[inline]
49+
fn next_u64(&mut self) -> u64 {
50+
wasi::random::insecure::get_insecure_random_u64()
51+
}
52+
53+
fn fill_bytes(&mut self, dest: &mut [u8]) {
54+
let n = dest.len();
55+
if usize::BITS <= u64::BITS || n <= u64::MAX as _ {
56+
dest.copy_from_slice(&wasi::random::insecure::get_insecure_random_bytes(n as _));
57+
} else {
58+
let (head, tail) = dest.split_at_mut(u64::MAX as _);
59+
head.copy_from_slice(&wasi::random::insecure::get_insecure_random_bytes(u64::MAX));
60+
self.fill_bytes(tail);
61+
}
62+
}
63+
64+
#[inline]
65+
fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> {
66+
self.fill_bytes(dest);
67+
Ok(())
68+
}
69+
}

examples/cli-command-no_std.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
wasi::cli::command::export!(Example);
2+
3+
struct Example;
4+
5+
impl wasi::exports::cli::run::Guest for Example {
6+
fn run() -> Result<(), ()> {
7+
let stdout = wasi::cli::stdout::get_stdout();
8+
stdout.blocking_write_and_flush(b"Hello, WASI!").unwrap();
9+
Ok(())
10+
}
11+
}

examples/cli-command.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
use std::io::Write as _;
2+
13
wasi::cli::command::export!(Example);
24

35
struct Example;
46

57
impl wasi::exports::cli::run::Guest for Example {
68
fn run() -> Result<(), ()> {
7-
let stdout = wasi::cli::stdout::get_stdout();
8-
stdout.blocking_write_and_flush(b"Hello, WASI!").unwrap();
9+
let mut stdout = wasi::cli::stdout::get_stdout();
10+
stdout.write_all(b"Hello, WASI!").unwrap();
11+
stdout.flush().unwrap();
912
Ok(())
1013
}
1114
}

examples/hello-world-no_std.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn main() {
2+
let stdout = wasi::cli::stdout::get_stdout();
3+
stdout.blocking_write_and_flush(b"Hello, world!\n").unwrap();
4+
}

examples/hello-world.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
use std::io::Write as _;
2+
13
fn main() {
2-
let stdout = wasi::cli::stdout::get_stdout();
3-
stdout.blocking_write_and_flush(b"Hello, world!\n").unwrap();
4+
let mut stdout = wasi::cli::stdout::get_stdout();
5+
stdout.write_all(b"Hello, world!\n").unwrap();
6+
stdout.flush().unwrap();
47
}

0 commit comments

Comments
 (0)