Skip to content
This repository was archived by the owner on Sep 8, 2025. It is now read-only.

Commit c72b8f8

Browse files
authored
feat: implement wasi:filesystem (#38)
Signed-off-by: Roman Volosatovs <rvolosatovs@riseup.net>
1 parent eef4b00 commit c72b8f8

9 files changed

Lines changed: 1806 additions & 194 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
use futures::{join, SinkExt as _, TryStreamExt as _};
2+
use test_programs::p3::wasi::filesystem::types::{DescriptorFlags, OpenFlags, PathFlags};
3+
use test_programs::p3::{wasi, wit_stream};
4+
5+
struct Component;
6+
7+
test_programs::p3::export!(Component);
8+
9+
impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
10+
async fn run() -> Result<(), ()> {
11+
let preopens = wasi::filesystem::preopens::get_directories();
12+
let (dir, _) = &preopens[0];
13+
14+
let filename = "test.txt";
15+
let file = dir
16+
.open_at(
17+
PathFlags::empty(),
18+
filename,
19+
OpenFlags::CREATE,
20+
DescriptorFlags::READ | DescriptorFlags::WRITE,
21+
)
22+
.unwrap();
23+
let (mut data_tx, data_rx) = wit_stream::new();
24+
join!(
25+
async {
26+
file.write_via_stream(data_rx, 5).await.unwrap();
27+
},
28+
async {
29+
data_tx.send(b"Hello, ".to_vec()).await.unwrap();
30+
data_tx.send(b"World!".to_vec()).await.unwrap();
31+
drop(data_tx);
32+
},
33+
);
34+
let (data_rx, data_fut) = file.read_via_stream(0);
35+
let contents = data_rx.try_collect::<Vec<_>>().await.unwrap().concat();
36+
data_fut.await.unwrap().unwrap().unwrap();
37+
assert_eq!(
38+
String::from_utf8_lossy(&contents),
39+
"\0\0\0\0\0Hello, World!"
40+
);
41+
42+
// Test that file read streams behave like other read streams.
43+
let (data_rx, data_fut) = file.read_via_stream(5);
44+
let contents = data_rx.try_collect::<Vec<_>>().await.unwrap().concat();
45+
data_fut.await.unwrap().unwrap().unwrap();
46+
assert_eq!(String::from_utf8_lossy(&contents), "Hello, World!");
47+
48+
dir.unlink_file_at(filename).unwrap();
49+
Ok(())
50+
}
51+
}
52+
53+
fn main() {}

crates/test-programs/src/p3/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ wit_bindgen::generate!({
99
imports: [
1010
"wasi:clocks/monotonic-clock@0.3.0#wait-for",
1111
"wasi:clocks/monotonic-clock@0.3.0#wait-until",
12+
"wasi:filesystem/types@0.3.0#[method]descriptor.write-via-stream",
1213
"wasi:sockets/ip-name-lookup@0.3.0#resolve-addresses",
1314
"wasi:sockets/types@0.3.0#[method]tcp-socket.connect",
1415
"wasi:sockets/types@0.3.0#[method]tcp-socket.send",

crates/wasi/src/p3/bindings.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,31 @@
5151
//! "example:wasi/custom-host#my-custom-function",
5252
//! "wasi:clocks/monotonic-clock@0.3.0#wait-for",
5353
//! "wasi:clocks/monotonic-clock@0.3.0#wait-until",
54+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.read-via-stream",
55+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.write-via-stream",
56+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.append-via-stream",
57+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.advise",
58+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.sync-data",
59+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.get-flags",
60+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.get-type",
61+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.set-size",
62+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.set-times",
63+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.read-directory",
64+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.sync",
65+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.create-directory-at",
66+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.stat",
67+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.stat-at",
68+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.set-times-at",
69+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.link-at",
70+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.open-at",
71+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.readlink-at",
72+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.remove-directory-at",
73+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.rename-at",
74+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.symlink-at",
75+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.unlink-file-at",
76+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.is-same-object",
77+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.metadata-hash",
78+
//! "wasi:filesystem/types@0.3.0#[method]descriptor.metadata-hash-at",
5479
//! "wasi:sockets/ip-name-lookup@0.3.0#resolve-addresses",
5580
//! "wasi:sockets/types@0.3.0#[method]tcp-socket.bind",
5681
//! "wasi:sockets/types@0.3.0#[method]tcp-socket.connect",
@@ -130,6 +155,31 @@ mod generated {
130155
only_imports: [
131156
"wasi:clocks/monotonic-clock@0.3.0#wait-for",
132157
"wasi:clocks/monotonic-clock@0.3.0#wait-until",
158+
"wasi:filesystem/types@0.3.0#[method]descriptor.read-via-stream",
159+
"wasi:filesystem/types@0.3.0#[method]descriptor.write-via-stream",
160+
"wasi:filesystem/types@0.3.0#[method]descriptor.append-via-stream",
161+
"wasi:filesystem/types@0.3.0#[method]descriptor.advise",
162+
"wasi:filesystem/types@0.3.0#[method]descriptor.sync-data",
163+
"wasi:filesystem/types@0.3.0#[method]descriptor.get-flags",
164+
"wasi:filesystem/types@0.3.0#[method]descriptor.get-type",
165+
"wasi:filesystem/types@0.3.0#[method]descriptor.set-size",
166+
"wasi:filesystem/types@0.3.0#[method]descriptor.set-times",
167+
"wasi:filesystem/types@0.3.0#[method]descriptor.read-directory",
168+
"wasi:filesystem/types@0.3.0#[method]descriptor.sync",
169+
"wasi:filesystem/types@0.3.0#[method]descriptor.create-directory-at",
170+
"wasi:filesystem/types@0.3.0#[method]descriptor.stat",
171+
"wasi:filesystem/types@0.3.0#[method]descriptor.stat-at",
172+
"wasi:filesystem/types@0.3.0#[method]descriptor.set-times-at",
173+
"wasi:filesystem/types@0.3.0#[method]descriptor.link-at",
174+
"wasi:filesystem/types@0.3.0#[method]descriptor.open-at",
175+
"wasi:filesystem/types@0.3.0#[method]descriptor.readlink-at",
176+
"wasi:filesystem/types@0.3.0#[method]descriptor.remove-directory-at",
177+
"wasi:filesystem/types@0.3.0#[method]descriptor.rename-at",
178+
"wasi:filesystem/types@0.3.0#[method]descriptor.symlink-at",
179+
"wasi:filesystem/types@0.3.0#[method]descriptor.unlink-file-at",
180+
"wasi:filesystem/types@0.3.0#[method]descriptor.is-same-object",
181+
"wasi:filesystem/types@0.3.0#[method]descriptor.metadata-hash",
182+
"wasi:filesystem/types@0.3.0#[method]descriptor.metadata-hash-at",
133183
"wasi:sockets/ip-name-lookup@0.3.0#resolve-addresses",
134184
"wasi:sockets/types@0.3.0#[method]tcp-socket.bind",
135185
"wasi:sockets/types@0.3.0#[method]tcp-socket.connect",
@@ -143,6 +193,7 @@ mod generated {
143193
],
144194
},
145195
with: {
196+
"wasi:filesystem/types/descriptor": crate::p3::filesystem::Descriptor,
146197
"wasi:sockets/types/tcp-socket": crate::p3::sockets::tcp::TcpSocket,
147198
"wasi:sockets/types/udp-socket": crate::p3::sockets::udp::UdpSocket,
148199
}

0 commit comments

Comments
 (0)