diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62e14c6..223eeed 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,7 @@ jobs: - name: Install Rust uses: dtolnay/rust-toolchain@1.78.0 with: + targets: wasm32-wasi components: clippy, rustfmt - name: cargo fmt run: cargo fmt --all -- --check @@ -26,6 +27,4 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} version: "v20.0.0" - name: cargo test - run: | - cargo install cargo-component@0.11.0 - cargo test + run: cargo test diff --git a/Cargo.toml b/Cargo.toml index 1ad283f..eebfafd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,10 @@ serde_urlencoded = "0.7.1" [features] json = ["dep:serde_json"] + +[dev-dependencies] +test-programs-artifacts = { path = "crates/test-programs/artifacts" } + +[workspace] +resolver = "2" +members = ["crates/test-programs"] diff --git a/crates/test-programs/Cargo.toml b/crates/test-programs/Cargo.toml new file mode 100644 index 0000000..a6f2bd3 --- /dev/null +++ b/crates/test-programs/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "test-programs" +version = "0.0.0" +edition = "2021" +publish = false + +[dependencies] +wasi-http-client = { path = "../../../wasi-http-client", features = ["json"] } +serde = { version = "1.0.201", features = ["derive"] } diff --git a/crates/test-programs/artifacts/Cargo.toml b/crates/test-programs/artifacts/Cargo.toml new file mode 100644 index 0000000..2d9cee8 --- /dev/null +++ b/crates/test-programs/artifacts/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "test-programs-artifacts" +version = "0.0.0" +edition = "2021" +publish = false + +[build-dependencies] +anyhow = "1.0.86" +cargo_metadata = "0.18.1" +wit-component = "0.208.1" +heck = "0.5.0" diff --git a/crates/test-programs/artifacts/build.rs b/crates/test-programs/artifacts/build.rs new file mode 100644 index 0000000..c770f1c --- /dev/null +++ b/crates/test-programs/artifacts/build.rs @@ -0,0 +1,70 @@ +use anyhow::Result; +use cargo_metadata::MetadataCommand; +use heck::*; +use std::path::{Path, PathBuf}; +use std::process::Command; +use std::{env, fs}; +use wit_component::ComponentEncoder; + +fn main() -> Result<()> { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + + println!("cargo::rerun-if-changed=../src"); + + let status = Command::new("cargo") + .arg("build") + .arg("--package=test-programs") + .arg("--target=wasm32-wasi") + .env("CARGO_TARGET_DIR", &out_dir) + .env("CARGO_PROFILE_DEV_DEBUG", "1") + .status()?; + assert!(status.success()); + + let meta = MetadataCommand::new().exec()?; + let targets = meta + .packages + .iter() + .find(|p| p.name == "test-programs") + .unwrap() + .targets + .iter() + .filter(|t| t.kind == ["bin"]) + .map(|t| &t.name) + .collect::>(); + + let mut generated_code = String::new(); + + for target in targets { + let camel = target.to_shouty_snake_case(); + let wasm = out_dir + .join("wasm32-wasi") + .join("debug") + .join(format!("{target}.wasm")); + + let path = compile_component(&wasm)?; + generated_code += &format!("pub const {camel}_COMPONENT: &'static str = {path:?};\n"); + } + + fs::write(out_dir.join("gen.rs"), generated_code)?; + + Ok(()) +} + +// Compile a component, return the path of the binary +fn compile_component(wasm: &Path) -> Result { + println!("creating a component from {wasm:?}"); + let module = fs::read(wasm)?; + let component = ComponentEncoder::default() + .module(module.as_slice())? + .validate(true) + .adapter( + "wasi_snapshot_preview1", + include_bytes!("wasi_snapshot_preview1.command.wasm"), + )? + .encode()?; + let out_dir = wasm.parent().unwrap(); + let stem = wasm.file_stem().unwrap().to_str().unwrap(); + let component_path = out_dir.join(format!("{stem}.component.wasm")); + fs::write(&component_path, component)?; + Ok(component_path) +} diff --git a/crates/test-programs/artifacts/src/lib.rs b/crates/test-programs/artifacts/src/lib.rs new file mode 100644 index 0000000..26a930a --- /dev/null +++ b/crates/test-programs/artifacts/src/lib.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/gen.rs")); diff --git a/crates/test-programs/artifacts/wasi_snapshot_preview1.command.wasm b/crates/test-programs/artifacts/wasi_snapshot_preview1.command.wasm new file mode 100644 index 0000000..626f7a9 Binary files /dev/null and b/crates/test-programs/artifacts/wasi_snapshot_preview1.command.wasm differ diff --git a/crates/test-programs/src/bin/get_chunk.rs b/crates/test-programs/src/bin/get_chunk.rs new file mode 100644 index 0000000..12ebbc2 --- /dev/null +++ b/crates/test-programs/src/bin/get_chunk.rs @@ -0,0 +1,14 @@ +use wasi_http_client::Client; + +fn main() { + let resp = Client::new() + .get("https://httpbin.org/range/20") + .query(&[("duration", "5"), ("chunk_size", "10")]) + .send() + .unwrap(); + assert_eq!(resp.status(), 200); + + while let Some(chunk) = resp.chunk(1024).unwrap() { + assert_eq!(String::from_utf8(chunk).unwrap().len(), 10); + } +} diff --git a/crates/test-programs/src/bin/get_with_json_response.rs b/crates/test-programs/src/bin/get_with_json_response.rs new file mode 100644 index 0000000..ebb81ee --- /dev/null +++ b/crates/test-programs/src/bin/get_with_json_response.rs @@ -0,0 +1,16 @@ +use serde::Deserialize; +use wasi_http_client::Client; + +#[derive(Deserialize)] +struct Data { + url: String, +} + +fn main() { + let resp = Client::new().get("https://httpbin.org/get").send().unwrap(); + let status = resp.status(); + assert_eq!(status, 200); + + let json_data = resp.json::().unwrap(); + assert_eq!(json_data.url, "https://httpbin.org/get") +} diff --git a/crates/test-programs/src/bin/get_with_query.rs b/crates/test-programs/src/bin/get_with_query.rs new file mode 100644 index 0000000..b31ba5c --- /dev/null +++ b/crates/test-programs/src/bin/get_with_query.rs @@ -0,0 +1,10 @@ +use wasi_http_client::Client; + +fn main() { + let resp = Client::new() + .get("https://httpbin.org/get?a=b") + .headers([("Content-Type", "application/json"), ("Accept", "*/*")]) + .send() + .unwrap(); + assert_eq!(resp.status(), 200); +} diff --git a/crates/test-programs/src/bin/post_with_form_data.rs b/crates/test-programs/src/bin/post_with_form_data.rs new file mode 100644 index 0000000..7f92f0a --- /dev/null +++ b/crates/test-programs/src/bin/post_with_form_data.rs @@ -0,0 +1,12 @@ +use std::time::Duration; +use wasi_http_client::Client; + +fn main() { + let resp = Client::new() + .post("https://httpbin.org/post") + .form(&[("a", "b"), ("c", "")]) + .connect_timeout(Duration::from_secs(5)) + .send() + .unwrap(); + assert_eq!(resp.status(), 200); +} diff --git a/crates/test-programs/src/bin/post_with_json_data.rs b/crates/test-programs/src/bin/post_with_json_data.rs new file mode 100644 index 0000000..3237472 --- /dev/null +++ b/crates/test-programs/src/bin/post_with_json_data.rs @@ -0,0 +1,13 @@ +use std::collections::HashMap; +use std::time::Duration; +use wasi_http_client::Client; + +fn main() { + let resp = Client::new() + .post("https://httpbin.org/post") + .json(&HashMap::from([("data", "hello")])) + .connect_timeout(Duration::from_secs(5)) + .send() + .unwrap(); + assert_eq!(resp.status(), 200); +} diff --git a/crates/test-programs/src/bin/post_with_multipart_form_data.rs b/crates/test-programs/src/bin/post_with_multipart_form_data.rs new file mode 100644 index 0000000..026d616 --- /dev/null +++ b/crates/test-programs/src/bin/post_with_multipart_form_data.rs @@ -0,0 +1,25 @@ +use std::time::Duration; +use wasi_http_client::Client; + +fn main() { + let resp = Client::new() + .post("https://httpbin.org/post") + .header("Content-Type", "multipart/form-data; boundary=boundary") + .body( + "--boundary +Content-Disposition: form-data; name=field1 + +value1 +--boundary +Content-Disposition: form-data; name=field2; filename=file.txt +Content-Type: text/plain + +hello +--boundary--" + .as_bytes(), + ) + .connect_timeout(Duration::from_secs(5)) + .send() + .unwrap(); + assert_eq!(resp.status(), 200); +} diff --git a/tests/main.rs b/tests/main.rs index 5c353c3..2b2c376 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -1,22 +1,67 @@ -use anyhow::Result; use std::process::Command; +fn wasmtime() -> Command { + let mut wasmtime = Command::new("wasmtime"); + wasmtime.arg("-S").arg("http"); + wasmtime +} + +#[test] +fn get_chunk() { + let mut cmd = wasmtime(); + let status = cmd + .arg(test_programs_artifacts::GET_CHUNK_COMPONENT) + .status() + .unwrap(); + assert!(status.success()); +} + #[test] -fn main() -> Result<()> { - let status = Command::new("cargo") - .current_dir("tests/program") - .arg("component") - .arg("build") - .arg("--quiet") - .status()?; +fn get_with_json_response() { + let mut cmd = wasmtime(); + let status = cmd + .arg(test_programs_artifacts::GET_WITH_JSON_RESPONSE_COMPONENT) + .status() + .unwrap(); assert!(status.success()); +} - let status = Command::new("wasmtime") - .arg("-S") - .arg("http") - .arg("tests/program/target/wasm32-wasi/debug/wasi_http_client_test_program.wasm") - .status()?; +#[test] +fn get_with_query() { + let mut cmd = wasmtime(); + let status = cmd + .arg(test_programs_artifacts::GET_WITH_QUERY_COMPONENT) + .status() + .unwrap(); assert!(status.success()); +} - Ok(()) +#[test] +fn post_with_form_data() { + let mut cmd = wasmtime(); + let status = cmd + .arg(test_programs_artifacts::POST_WITH_FORM_DATA_COMPONENT) + .status() + .unwrap(); + assert!(status.success()); +} + +#[test] +fn post_with_json_data() { + let mut cmd = wasmtime(); + let status = cmd + .arg(test_programs_artifacts::POST_WITH_JSON_DATA_COMPONENT) + .status() + .unwrap(); + assert!(status.success()); +} + +#[test] +fn post_with_multipart_form_data() { + let mut cmd = wasmtime(); + let status = cmd + .arg(test_programs_artifacts::POST_WITH_MULTIPART_FORM_DATA_COMPONENT) + .status() + .unwrap(); + assert!(status.success()); } diff --git a/tests/program/Cargo.toml b/tests/program/Cargo.toml deleted file mode 100644 index 0e3daeb..0000000 --- a/tests/program/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "wasi-http-client-test-program" -version = "0.0.0" -edition = "2021" -publish = false - -[lib] -crate-type = ["cdylib"] - -[package.metadata.component] -package = "component:wasi-http-client-test-program" - -[package.metadata.component.dependencies] - -[package.metadata.component.target.dependencies] -"wasi:cli" = { path = "wit/deps/cli" } -"wasi:io" = { path = "wit/deps/io" } -"wasi:clocks" = { path = "wit/deps/clocks" } -"wasi:filesystem" = { path = "wit/deps/filesystem" } -"wasi:sockets" = { path = "wit/deps/sockets" } -"wasi:random" = { path = "wit/deps/random" } - -[dependencies] -wasi-http-client = { path = "../../../wasi-http-client", features = ["json"] } - -wit-bindgen-rt = { version = "0.24.0", features = ["bitflags"] } -serde = { version = "1.0.201", features = ["derive"] } diff --git a/tests/program/src/bindings.rs b/tests/program/src/bindings.rs deleted file mode 100644 index 3962cee..0000000 --- a/tests/program/src/bindings.rs +++ /dev/null @@ -1,9594 +0,0 @@ -// Generated by `wit-bindgen` 0.24.0. DO NOT EDIT! -// Options used: -#[allow(dead_code)] -pub mod wasi { - #[allow(dead_code)] - pub mod cli { - #[allow(dead_code, clippy::all)] - pub mod environment { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - #[allow(unused_unsafe, clippy::all)] - /// Get the POSIX-style environment variables. - /// - /// Each environment variable is provided as a pair of string variable names - /// and string value. - /// - /// Morally, these are a value import, but until value imports are available - /// in the component model, this import function should return the same - /// values each time it is called. - pub fn get_environment() -> _rt::Vec<(_rt::String, _rt::String)> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:cli/environment@0.2.0")] - extern "C" { - #[link_name = "get-environment"] - fn wit_import(_: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8) { - unreachable!() - } - wit_import(ptr0); - let l1 = *ptr0.add(0).cast::<*mut u8>(); - let l2 = *ptr0.add(4).cast::(); - let base9 = l1; - let len9 = l2; - let mut result9 = _rt::Vec::with_capacity(len9); - for i in 0..len9 { - let base = base9.add(i * 16); - let e9 = { - let l3 = *base.add(0).cast::<*mut u8>(); - let l4 = *base.add(4).cast::(); - let len5 = l4; - let bytes5 = _rt::Vec::from_raw_parts(l3.cast(), len5, len5); - let l6 = *base.add(8).cast::<*mut u8>(); - let l7 = *base.add(12).cast::(); - let len8 = l7; - let bytes8 = _rt::Vec::from_raw_parts(l6.cast(), len8, len8); - - (_rt::string_lift(bytes5), _rt::string_lift(bytes8)) - }; - result9.push(e9); - } - _rt::cabi_dealloc(base9, len9 * 16, 4); - result9 - } - } - #[allow(unused_unsafe, clippy::all)] - /// Get the POSIX-style arguments to the program. - pub fn get_arguments() -> _rt::Vec<_rt::String> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:cli/environment@0.2.0")] - extern "C" { - #[link_name = "get-arguments"] - fn wit_import(_: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8) { - unreachable!() - } - wit_import(ptr0); - let l1 = *ptr0.add(0).cast::<*mut u8>(); - let l2 = *ptr0.add(4).cast::(); - let base6 = l1; - let len6 = l2; - let mut result6 = _rt::Vec::with_capacity(len6); - for i in 0..len6 { - let base = base6.add(i * 8); - let e6 = { - let l3 = *base.add(0).cast::<*mut u8>(); - let l4 = *base.add(4).cast::(); - let len5 = l4; - let bytes5 = _rt::Vec::from_raw_parts(l3.cast(), len5, len5); - - _rt::string_lift(bytes5) - }; - result6.push(e6); - } - _rt::cabi_dealloc(base6, len6 * 8, 4); - result6 - } - } - #[allow(unused_unsafe, clippy::all)] - /// Return a path that programs should use as their initial current working - /// directory, interpreting `.` as shorthand for this. - pub fn initial_cwd() -> Option<_rt::String> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:cli/environment@0.2.0")] - extern "C" { - #[link_name = "initial-cwd"] - fn wit_import(_: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8) { - unreachable!() - } - wit_import(ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => None, - 1 => { - let e = { - let l2 = *ptr0.add(4).cast::<*mut u8>(); - let l3 = *ptr0.add(8).cast::(); - let len4 = l3; - let bytes4 = _rt::Vec::from_raw_parts(l2.cast(), len4, len4); - - _rt::string_lift(bytes4) - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod exit { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - #[allow(unused_unsafe, clippy::all)] - /// Exit the current instance and any linked instances. - pub fn exit(status: Result<(), ()>) { - unsafe { - let result0 = match status { - Ok(_) => 0i32, - Err(_) => 1i32, - }; - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:cli/exit@0.2.0")] - extern "C" { - #[link_name = "exit"] - fn wit_import(_: i32); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) { - unreachable!() - } - wit_import(result0); - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod stdin { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - pub type InputStream = super::super::super::wasi::io::streams::InputStream; - #[allow(unused_unsafe, clippy::all)] - pub fn get_stdin() -> InputStream { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:cli/stdin@0.2.0")] - extern "C" { - #[link_name = "get-stdin"] - fn wit_import() -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i32 { - unreachable!() - } - let ret = wit_import(); - super::super::super::wasi::io::streams::InputStream::from_handle(ret as u32) - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod stdout { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - pub type OutputStream = super::super::super::wasi::io::streams::OutputStream; - #[allow(unused_unsafe, clippy::all)] - pub fn get_stdout() -> OutputStream { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:cli/stdout@0.2.0")] - extern "C" { - #[link_name = "get-stdout"] - fn wit_import() -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i32 { - unreachable!() - } - let ret = wit_import(); - super::super::super::wasi::io::streams::OutputStream::from_handle(ret as u32) - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod stderr { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - pub type OutputStream = super::super::super::wasi::io::streams::OutputStream; - #[allow(unused_unsafe, clippy::all)] - pub fn get_stderr() -> OutputStream { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:cli/stderr@0.2.0")] - extern "C" { - #[link_name = "get-stderr"] - fn wit_import() -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i32 { - unreachable!() - } - let ret = wit_import(); - super::super::super::wasi::io::streams::OutputStream::from_handle(ret as u32) - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod terminal_input { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - /// The input side of a terminal. - - #[derive(Debug)] - #[repr(transparent)] - pub struct TerminalInput { - handle: _rt::Resource, - } - - impl TerminalInput { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for TerminalInput { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:cli/terminal-input@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]terminal-input"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod terminal_output { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - /// The output side of a terminal. - - #[derive(Debug)] - #[repr(transparent)] - pub struct TerminalOutput { - handle: _rt::Resource, - } - - impl TerminalOutput { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for TerminalOutput { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:cli/terminal-output@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]terminal-output"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod terminal_stdin { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type TerminalInput = super::super::super::wasi::cli::terminal_input::TerminalInput; - #[allow(unused_unsafe, clippy::all)] - /// If stdin is connected to a terminal, return a `terminal-input` handle - /// allowing further interaction with it. - pub fn get_terminal_stdin() -> Option { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:cli/terminal-stdin@0.2.0")] - extern "C" { - #[link_name = "get-terminal-stdin"] - fn wit_import(_: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8) { - unreachable!() - } - wit_import(ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => None, - 1 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - - super::super::super::wasi::cli::terminal_input::TerminalInput::from_handle(l2 as u32) - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod terminal_stdout { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type TerminalOutput = - super::super::super::wasi::cli::terminal_output::TerminalOutput; - #[allow(unused_unsafe, clippy::all)] - /// If stdout is connected to a terminal, return a `terminal-output` handle - /// allowing further interaction with it. - pub fn get_terminal_stdout() -> Option { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:cli/terminal-stdout@0.2.0")] - extern "C" { - #[link_name = "get-terminal-stdout"] - fn wit_import(_: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8) { - unreachable!() - } - wit_import(ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => None, - 1 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - - super::super::super::wasi::cli::terminal_output::TerminalOutput::from_handle(l2 as u32) - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod terminal_stderr { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type TerminalOutput = - super::super::super::wasi::cli::terminal_output::TerminalOutput; - #[allow(unused_unsafe, clippy::all)] - /// If stderr is connected to a terminal, return a `terminal-output` handle - /// allowing further interaction with it. - pub fn get_terminal_stderr() -> Option { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:cli/terminal-stderr@0.2.0")] - extern "C" { - #[link_name = "get-terminal-stderr"] - fn wit_import(_: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8) { - unreachable!() - } - wit_import(ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => None, - 1 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - - super::super::super::wasi::cli::terminal_output::TerminalOutput::from_handle(l2 as u32) - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - } - #[allow(dead_code)] - pub mod clocks { - #[allow(dead_code, clippy::all)] - pub mod monotonic_clock { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type Pollable = super::super::super::wasi::io::poll::Pollable; - /// An instant in time, in nanoseconds. An instant is relative to an - /// unspecified initial value, and can only be compared to instances from - /// the same monotonic-clock. - pub type Instant = u64; - /// A duration of time, in nanoseconds. - pub type Duration = u64; - #[allow(unused_unsafe, clippy::all)] - /// Read the current value of the clock. - /// - /// The clock is monotonic, therefore calling this function repeatedly will - /// produce a sequence of non-decreasing values. - pub fn now() -> Instant { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:clocks/monotonic-clock@0.2.0")] - extern "C" { - #[link_name = "now"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64 { - unreachable!() - } - let ret = wit_import(); - ret as u64 - } - } - #[allow(unused_unsafe, clippy::all)] - /// Query the resolution of the clock. Returns the duration of time - /// corresponding to a clock tick. - pub fn resolution() -> Duration { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:clocks/monotonic-clock@0.2.0")] - extern "C" { - #[link_name = "resolution"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64 { - unreachable!() - } - let ret = wit_import(); - ret as u64 - } - } - #[allow(unused_unsafe, clippy::all)] - /// Create a `pollable` which will resolve once the specified instant - /// occured. - pub fn subscribe_instant(when: Instant) -> Pollable { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:clocks/monotonic-clock@0.2.0")] - extern "C" { - #[link_name = "subscribe-instant"] - fn wit_import(_: i64) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64) -> i32 { - unreachable!() - } - let ret = wit_import(_rt::as_i64(when)); - super::super::super::wasi::io::poll::Pollable::from_handle(ret as u32) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Create a `pollable` which will resolve once the given duration has - /// elapsed, starting at the time at which this function was called. - /// occured. - pub fn subscribe_duration(when: Duration) -> Pollable { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:clocks/monotonic-clock@0.2.0")] - extern "C" { - #[link_name = "subscribe-duration"] - fn wit_import(_: i64) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64) -> i32 { - unreachable!() - } - let ret = wit_import(_rt::as_i64(when)); - super::super::super::wasi::io::poll::Pollable::from_handle(ret as u32) - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod wall_clock { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - /// A time and date in seconds plus nanoseconds. - #[repr(C)] - #[derive(Clone, Copy)] - pub struct Datetime { - pub seconds: u64, - pub nanoseconds: u32, - } - impl ::core::fmt::Debug for Datetime { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Datetime") - .field("seconds", &self.seconds) - .field("nanoseconds", &self.nanoseconds) - .finish() - } - } - #[allow(unused_unsafe, clippy::all)] - /// Read the current value of the clock. - /// - /// This clock is not monotonic, therefore calling this function repeatedly - /// will not necessarily produce a sequence of non-decreasing values. - /// - /// The returned timestamps represent the number of seconds since - /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], - /// also known as [Unix Time]. - /// - /// The nanoseconds field of the output is always less than 1000000000. - /// - /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 - /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - pub fn now() -> Datetime { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:clocks/wall-clock@0.2.0")] - extern "C" { - #[link_name = "now"] - fn wit_import(_: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8) { - unreachable!() - } - wit_import(ptr0); - let l1 = *ptr0.add(0).cast::(); - let l2 = *ptr0.add(8).cast::(); - Datetime { - seconds: l1 as u64, - nanoseconds: l2 as u32, - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Query the resolution of the clock. - /// - /// The nanoseconds field of the output is always less than 1000000000. - pub fn resolution() -> Datetime { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:clocks/wall-clock@0.2.0")] - extern "C" { - #[link_name = "resolution"] - fn wit_import(_: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8) { - unreachable!() - } - wit_import(ptr0); - let l1 = *ptr0.add(0).cast::(); - let l2 = *ptr0.add(8).cast::(); - Datetime { - seconds: l1 as u64, - nanoseconds: l2 as u32, - } - } - } - } - } - #[allow(dead_code)] - pub mod filesystem { - #[allow(dead_code, clippy::all)] - pub mod types { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type InputStream = super::super::super::wasi::io::streams::InputStream; - pub type OutputStream = super::super::super::wasi::io::streams::OutputStream; - pub type Error = super::super::super::wasi::io::streams::Error; - pub type Datetime = super::super::super::wasi::clocks::wall_clock::Datetime; - /// File size or length of a region within a file. - pub type Filesize = u64; - /// The type of a filesystem object referenced by a descriptor. - /// - /// Note: This was called `filetype` in earlier versions of WASI. - #[repr(u8)] - #[derive(Clone, Copy, Eq, PartialEq)] - pub enum DescriptorType { - /// The type of the descriptor or file is unknown or is different from - /// any of the other types specified. - Unknown, - /// The descriptor refers to a block device inode. - BlockDevice, - /// The descriptor refers to a character device inode. - CharacterDevice, - /// The descriptor refers to a directory inode. - Directory, - /// The descriptor refers to a named pipe. - Fifo, - /// The file refers to a symbolic link inode. - SymbolicLink, - /// The descriptor refers to a regular file inode. - RegularFile, - /// The descriptor refers to a socket. - Socket, - } - impl ::core::fmt::Debug for DescriptorType { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - DescriptorType::Unknown => { - f.debug_tuple("DescriptorType::Unknown").finish() - } - DescriptorType::BlockDevice => { - f.debug_tuple("DescriptorType::BlockDevice").finish() - } - DescriptorType::CharacterDevice => { - f.debug_tuple("DescriptorType::CharacterDevice").finish() - } - DescriptorType::Directory => { - f.debug_tuple("DescriptorType::Directory").finish() - } - DescriptorType::Fifo => f.debug_tuple("DescriptorType::Fifo").finish(), - DescriptorType::SymbolicLink => { - f.debug_tuple("DescriptorType::SymbolicLink").finish() - } - DescriptorType::RegularFile => { - f.debug_tuple("DescriptorType::RegularFile").finish() - } - DescriptorType::Socket => f.debug_tuple("DescriptorType::Socket").finish(), - } - } - } - - impl DescriptorType { - pub(crate) unsafe fn _lift(val: u8) -> DescriptorType { - if !cfg!(debug_assertions) { - return ::core::mem::transmute(val); - } - - match val { - 0 => DescriptorType::Unknown, - 1 => DescriptorType::BlockDevice, - 2 => DescriptorType::CharacterDevice, - 3 => DescriptorType::Directory, - 4 => DescriptorType::Fifo, - 5 => DescriptorType::SymbolicLink, - 6 => DescriptorType::RegularFile, - 7 => DescriptorType::Socket, - - _ => panic!("invalid enum discriminant"), - } - } - } - - wit_bindgen_rt::bitflags::bitflags! { - /// Descriptor flags. - /// - /// Note: This was called `fdflags` in earlier versions of WASI. - #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] - pub struct DescriptorFlags: u8 { - /// Read mode: Data can be read. - const READ = 1 << 0; - /// Write mode: Data can be written to. - const WRITE = 1 << 1; - /// Request that writes be performed according to synchronized I/O file - /// integrity completion. The data stored in the file and the file's - /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - const FILE_INTEGRITY_SYNC = 1 << 2; - /// Request that writes be performed according to synchronized I/O data - /// integrity completion. Only the data stored in the file is - /// synchronized. This is similar to `O_DSYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - const DATA_INTEGRITY_SYNC = 1 << 3; - /// Requests that reads be performed at the same level of integrety - /// requested for writes. This is similar to `O_RSYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - const REQUESTED_WRITE_SYNC = 1 << 4; - /// Mutating directories mode: Directory contents may be mutated. - /// - /// When this flag is unset on a descriptor, operations using the - /// descriptor which would create, rename, delete, modify the data or - /// metadata of filesystem objects, or obtain another handle which - /// would permit any of those, shall fail with `error-code::read-only` if - /// they would otherwise succeed. - /// - /// This may only be set on directories. - const MUTATE_DIRECTORY = 1 << 5; - } - } - wit_bindgen_rt::bitflags::bitflags! { - /// Flags determining the method of how paths are resolved. - #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] - pub struct PathFlags: u8 { - /// As long as the resolved path corresponds to a symbolic link, it is - /// expanded. - const SYMLINK_FOLLOW = 1 << 0; - } - } - wit_bindgen_rt::bitflags::bitflags! { - /// Open flags used by `open-at`. - #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] - pub struct OpenFlags: u8 { - /// Create file if it does not exist, similar to `O_CREAT` in POSIX. - const CREATE = 1 << 0; - /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. - const DIRECTORY = 1 << 1; - /// Fail if file already exists, similar to `O_EXCL` in POSIX. - const EXCLUSIVE = 1 << 2; - /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. - const TRUNCATE = 1 << 3; - } - } - /// Number of hard links to an inode. - pub type LinkCount = u64; - /// File attributes. - /// - /// Note: This was called `filestat` in earlier versions of WASI. - #[repr(C)] - #[derive(Clone, Copy)] - pub struct DescriptorStat { - /// File type. - pub type_: DescriptorType, - /// Number of hard links to the file. - pub link_count: LinkCount, - /// For regular files, the file size in bytes. For symbolic links, the - /// length in bytes of the pathname contained in the symbolic link. - pub size: Filesize, - /// Last data access timestamp. - /// - /// If the `option` is none, the platform doesn't maintain an access - /// timestamp for this file. - pub data_access_timestamp: Option, - /// Last data modification timestamp. - /// - /// If the `option` is none, the platform doesn't maintain a - /// modification timestamp for this file. - pub data_modification_timestamp: Option, - /// Last file status-change timestamp. - /// - /// If the `option` is none, the platform doesn't maintain a - /// status-change timestamp for this file. - pub status_change_timestamp: Option, - } - impl ::core::fmt::Debug for DescriptorStat { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("DescriptorStat") - .field("type", &self.type_) - .field("link-count", &self.link_count) - .field("size", &self.size) - .field("data-access-timestamp", &self.data_access_timestamp) - .field( - "data-modification-timestamp", - &self.data_modification_timestamp, - ) - .field("status-change-timestamp", &self.status_change_timestamp) - .finish() - } - } - /// When setting a timestamp, this gives the value to set it to. - #[derive(Clone, Copy)] - pub enum NewTimestamp { - /// Leave the timestamp set to its previous value. - NoChange, - /// Set the timestamp to the current time of the system clock associated - /// with the filesystem. - Now, - /// Set the timestamp to the given value. - Timestamp(Datetime), - } - impl ::core::fmt::Debug for NewTimestamp { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - NewTimestamp::NoChange => f.debug_tuple("NewTimestamp::NoChange").finish(), - NewTimestamp::Now => f.debug_tuple("NewTimestamp::Now").finish(), - NewTimestamp::Timestamp(e) => { - f.debug_tuple("NewTimestamp::Timestamp").field(e).finish() - } - } - } - } - /// A directory entry. - #[derive(Clone)] - pub struct DirectoryEntry { - /// The type of the file referred to by this directory entry. - pub type_: DescriptorType, - /// The name of the object. - pub name: _rt::String, - } - impl ::core::fmt::Debug for DirectoryEntry { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("DirectoryEntry") - .field("type", &self.type_) - .field("name", &self.name) - .finish() - } - } - /// Error codes returned by functions, similar to `errno` in POSIX. - /// Not all of these error codes are returned by the functions provided by this - /// API; some are used in higher-level library layers, and others are provided - /// merely for alignment with POSIX. - #[repr(u8)] - #[derive(Clone, Copy, Eq, PartialEq)] - pub enum ErrorCode { - /// Permission denied, similar to `EACCES` in POSIX. - Access, - /// Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. - WouldBlock, - /// Connection already in progress, similar to `EALREADY` in POSIX. - Already, - /// Bad descriptor, similar to `EBADF` in POSIX. - BadDescriptor, - /// Device or resource busy, similar to `EBUSY` in POSIX. - Busy, - /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. - Deadlock, - /// Storage quota exceeded, similar to `EDQUOT` in POSIX. - Quota, - /// File exists, similar to `EEXIST` in POSIX. - Exist, - /// File too large, similar to `EFBIG` in POSIX. - FileTooLarge, - /// Illegal byte sequence, similar to `EILSEQ` in POSIX. - IllegalByteSequence, - /// Operation in progress, similar to `EINPROGRESS` in POSIX. - InProgress, - /// Interrupted function, similar to `EINTR` in POSIX. - Interrupted, - /// Invalid argument, similar to `EINVAL` in POSIX. - Invalid, - /// I/O error, similar to `EIO` in POSIX. - Io, - /// Is a directory, similar to `EISDIR` in POSIX. - IsDirectory, - /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. - Loop, - /// Too many links, similar to `EMLINK` in POSIX. - TooManyLinks, - /// Message too large, similar to `EMSGSIZE` in POSIX. - MessageSize, - /// Filename too long, similar to `ENAMETOOLONG` in POSIX. - NameTooLong, - /// No such device, similar to `ENODEV` in POSIX. - NoDevice, - /// No such file or directory, similar to `ENOENT` in POSIX. - NoEntry, - /// No locks available, similar to `ENOLCK` in POSIX. - NoLock, - /// Not enough space, similar to `ENOMEM` in POSIX. - InsufficientMemory, - /// No space left on device, similar to `ENOSPC` in POSIX. - InsufficientSpace, - /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. - NotDirectory, - /// Directory not empty, similar to `ENOTEMPTY` in POSIX. - NotEmpty, - /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. - NotRecoverable, - /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. - Unsupported, - /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. - NoTty, - /// No such device or address, similar to `ENXIO` in POSIX. - NoSuchDevice, - /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. - Overflow, - /// Operation not permitted, similar to `EPERM` in POSIX. - NotPermitted, - /// Broken pipe, similar to `EPIPE` in POSIX. - Pipe, - /// Read-only file system, similar to `EROFS` in POSIX. - ReadOnly, - /// Invalid seek, similar to `ESPIPE` in POSIX. - InvalidSeek, - /// Text file busy, similar to `ETXTBSY` in POSIX. - TextFileBusy, - /// Cross-device link, similar to `EXDEV` in POSIX. - CrossDevice, - } - impl ErrorCode { - pub fn name(&self) -> &'static str { - match self { - ErrorCode::Access => "access", - ErrorCode::WouldBlock => "would-block", - ErrorCode::Already => "already", - ErrorCode::BadDescriptor => "bad-descriptor", - ErrorCode::Busy => "busy", - ErrorCode::Deadlock => "deadlock", - ErrorCode::Quota => "quota", - ErrorCode::Exist => "exist", - ErrorCode::FileTooLarge => "file-too-large", - ErrorCode::IllegalByteSequence => "illegal-byte-sequence", - ErrorCode::InProgress => "in-progress", - ErrorCode::Interrupted => "interrupted", - ErrorCode::Invalid => "invalid", - ErrorCode::Io => "io", - ErrorCode::IsDirectory => "is-directory", - ErrorCode::Loop => "loop", - ErrorCode::TooManyLinks => "too-many-links", - ErrorCode::MessageSize => "message-size", - ErrorCode::NameTooLong => "name-too-long", - ErrorCode::NoDevice => "no-device", - ErrorCode::NoEntry => "no-entry", - ErrorCode::NoLock => "no-lock", - ErrorCode::InsufficientMemory => "insufficient-memory", - ErrorCode::InsufficientSpace => "insufficient-space", - ErrorCode::NotDirectory => "not-directory", - ErrorCode::NotEmpty => "not-empty", - ErrorCode::NotRecoverable => "not-recoverable", - ErrorCode::Unsupported => "unsupported", - ErrorCode::NoTty => "no-tty", - ErrorCode::NoSuchDevice => "no-such-device", - ErrorCode::Overflow => "overflow", - ErrorCode::NotPermitted => "not-permitted", - ErrorCode::Pipe => "pipe", - ErrorCode::ReadOnly => "read-only", - ErrorCode::InvalidSeek => "invalid-seek", - ErrorCode::TextFileBusy => "text-file-busy", - ErrorCode::CrossDevice => "cross-device", - } - } - pub fn message(&self) -> &'static str { - match self { - ErrorCode::Access => "Permission denied, similar to `EACCES` in POSIX.", - ErrorCode::WouldBlock => "Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX.", - ErrorCode::Already => "Connection already in progress, similar to `EALREADY` in POSIX.", - ErrorCode::BadDescriptor => "Bad descriptor, similar to `EBADF` in POSIX.", - ErrorCode::Busy => "Device or resource busy, similar to `EBUSY` in POSIX.", - ErrorCode::Deadlock => "Resource deadlock would occur, similar to `EDEADLK` in POSIX.", - ErrorCode::Quota => "Storage quota exceeded, similar to `EDQUOT` in POSIX.", - ErrorCode::Exist => "File exists, similar to `EEXIST` in POSIX.", - ErrorCode::FileTooLarge => "File too large, similar to `EFBIG` in POSIX.", - ErrorCode::IllegalByteSequence => "Illegal byte sequence, similar to `EILSEQ` in POSIX.", - ErrorCode::InProgress => "Operation in progress, similar to `EINPROGRESS` in POSIX.", - ErrorCode::Interrupted => "Interrupted function, similar to `EINTR` in POSIX.", - ErrorCode::Invalid => "Invalid argument, similar to `EINVAL` in POSIX.", - ErrorCode::Io => "I/O error, similar to `EIO` in POSIX.", - ErrorCode::IsDirectory => "Is a directory, similar to `EISDIR` in POSIX.", - ErrorCode::Loop => "Too many levels of symbolic links, similar to `ELOOP` in POSIX.", - ErrorCode::TooManyLinks => "Too many links, similar to `EMLINK` in POSIX.", - ErrorCode::MessageSize => "Message too large, similar to `EMSGSIZE` in POSIX.", - ErrorCode::NameTooLong => "Filename too long, similar to `ENAMETOOLONG` in POSIX.", - ErrorCode::NoDevice => "No such device, similar to `ENODEV` in POSIX.", - ErrorCode::NoEntry => "No such file or directory, similar to `ENOENT` in POSIX.", - ErrorCode::NoLock => "No locks available, similar to `ENOLCK` in POSIX.", - ErrorCode::InsufficientMemory => "Not enough space, similar to `ENOMEM` in POSIX.", - ErrorCode::InsufficientSpace => "No space left on device, similar to `ENOSPC` in POSIX.", - ErrorCode::NotDirectory => "Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX.", - ErrorCode::NotEmpty => "Directory not empty, similar to `ENOTEMPTY` in POSIX.", - ErrorCode::NotRecoverable => "State not recoverable, similar to `ENOTRECOVERABLE` in POSIX.", - ErrorCode::Unsupported => "Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX.", - ErrorCode::NoTty => "Inappropriate I/O control operation, similar to `ENOTTY` in POSIX.", - ErrorCode::NoSuchDevice => "No such device or address, similar to `ENXIO` in POSIX.", - ErrorCode::Overflow => "Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX.", - ErrorCode::NotPermitted => "Operation not permitted, similar to `EPERM` in POSIX.", - ErrorCode::Pipe => "Broken pipe, similar to `EPIPE` in POSIX.", - ErrorCode::ReadOnly => "Read-only file system, similar to `EROFS` in POSIX.", - ErrorCode::InvalidSeek => "Invalid seek, similar to `ESPIPE` in POSIX.", - ErrorCode::TextFileBusy => "Text file busy, similar to `ETXTBSY` in POSIX.", - ErrorCode::CrossDevice => "Cross-device link, similar to `EXDEV` in POSIX.", - } - } - } - impl ::core::fmt::Debug for ErrorCode { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("ErrorCode") - .field("code", &(*self as i32)) - .field("name", &self.name()) - .field("message", &self.message()) - .finish() - } - } - impl ::core::fmt::Display for ErrorCode { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write!(f, "{} (error {})", self.name(), *self as i32) - } - } - - impl std::error::Error for ErrorCode {} - - impl ErrorCode { - pub(crate) unsafe fn _lift(val: u8) -> ErrorCode { - if !cfg!(debug_assertions) { - return ::core::mem::transmute(val); - } - - match val { - 0 => ErrorCode::Access, - 1 => ErrorCode::WouldBlock, - 2 => ErrorCode::Already, - 3 => ErrorCode::BadDescriptor, - 4 => ErrorCode::Busy, - 5 => ErrorCode::Deadlock, - 6 => ErrorCode::Quota, - 7 => ErrorCode::Exist, - 8 => ErrorCode::FileTooLarge, - 9 => ErrorCode::IllegalByteSequence, - 10 => ErrorCode::InProgress, - 11 => ErrorCode::Interrupted, - 12 => ErrorCode::Invalid, - 13 => ErrorCode::Io, - 14 => ErrorCode::IsDirectory, - 15 => ErrorCode::Loop, - 16 => ErrorCode::TooManyLinks, - 17 => ErrorCode::MessageSize, - 18 => ErrorCode::NameTooLong, - 19 => ErrorCode::NoDevice, - 20 => ErrorCode::NoEntry, - 21 => ErrorCode::NoLock, - 22 => ErrorCode::InsufficientMemory, - 23 => ErrorCode::InsufficientSpace, - 24 => ErrorCode::NotDirectory, - 25 => ErrorCode::NotEmpty, - 26 => ErrorCode::NotRecoverable, - 27 => ErrorCode::Unsupported, - 28 => ErrorCode::NoTty, - 29 => ErrorCode::NoSuchDevice, - 30 => ErrorCode::Overflow, - 31 => ErrorCode::NotPermitted, - 32 => ErrorCode::Pipe, - 33 => ErrorCode::ReadOnly, - 34 => ErrorCode::InvalidSeek, - 35 => ErrorCode::TextFileBusy, - 36 => ErrorCode::CrossDevice, - - _ => panic!("invalid enum discriminant"), - } - } - } - - /// File or memory access pattern advisory information. - #[repr(u8)] - #[derive(Clone, Copy, Eq, PartialEq)] - pub enum Advice { - /// The application has no advice to give on its behavior with respect - /// to the specified data. - Normal, - /// The application expects to access the specified data sequentially - /// from lower offsets to higher offsets. - Sequential, - /// The application expects to access the specified data in a random - /// order. - Random, - /// The application expects to access the specified data in the near - /// future. - WillNeed, - /// The application expects that it will not access the specified data - /// in the near future. - DontNeed, - /// The application expects to access the specified data once and then - /// not reuse it thereafter. - NoReuse, - } - impl ::core::fmt::Debug for Advice { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - Advice::Normal => f.debug_tuple("Advice::Normal").finish(), - Advice::Sequential => f.debug_tuple("Advice::Sequential").finish(), - Advice::Random => f.debug_tuple("Advice::Random").finish(), - Advice::WillNeed => f.debug_tuple("Advice::WillNeed").finish(), - Advice::DontNeed => f.debug_tuple("Advice::DontNeed").finish(), - Advice::NoReuse => f.debug_tuple("Advice::NoReuse").finish(), - } - } - } - - impl Advice { - pub(crate) unsafe fn _lift(val: u8) -> Advice { - if !cfg!(debug_assertions) { - return ::core::mem::transmute(val); - } - - match val { - 0 => Advice::Normal, - 1 => Advice::Sequential, - 2 => Advice::Random, - 3 => Advice::WillNeed, - 4 => Advice::DontNeed, - 5 => Advice::NoReuse, - - _ => panic!("invalid enum discriminant"), - } - } - } - - /// A 128-bit hash value, split into parts because wasm doesn't have a - /// 128-bit integer type. - #[repr(C)] - #[derive(Clone, Copy)] - pub struct MetadataHashValue { - /// 64 bits of a 128-bit hash value. - pub lower: u64, - /// Another 64 bits of a 128-bit hash value. - pub upper: u64, - } - impl ::core::fmt::Debug for MetadataHashValue { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("MetadataHashValue") - .field("lower", &self.lower) - .field("upper", &self.upper) - .finish() - } - } - /// A descriptor is a reference to a filesystem object, which may be a file, - /// directory, named pipe, special file, or other object on which filesystem - /// calls may be made. - - #[derive(Debug)] - #[repr(transparent)] - pub struct Descriptor { - handle: _rt::Resource, - } - - impl Descriptor { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for Descriptor { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]descriptor"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - /// A stream of directory entries. - - #[derive(Debug)] - #[repr(transparent)] - pub struct DirectoryEntryStream { - handle: _rt::Resource, - } - - impl DirectoryEntryStream { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for DirectoryEntryStream { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]directory-entry-stream"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Return a stream for reading from a file, if available. - /// - /// May fail with an error-code describing why the file cannot be read. - /// - /// Multiple read, write, and append streams may be active on the same open - /// file and they do not interfere with each other. - /// - /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. - pub fn read_via_stream(&self, offset: Filesize) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.read-via-stream"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(offset), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - - super::super::super::wasi::io::streams::InputStream::from_handle( - l2 as u32, - ) - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(4).cast::()); - - ErrorCode::_lift(l3 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Return a stream for writing to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be written. - /// - /// Note: This allows using `write-stream`, which is similar to `write` in - /// POSIX. - pub fn write_via_stream( - &self, - offset: Filesize, - ) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.write-via-stream"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(offset), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - - super::super::super::wasi::io::streams::OutputStream::from_handle(l2 as u32) - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(4).cast::()); - - ErrorCode::_lift(l3 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Return a stream for appending to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be appended. - /// - /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in in POSIX. - pub fn append_via_stream(&self) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.append-via-stream"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - - super::super::super::wasi::io::streams::OutputStream::from_handle(l2 as u32) - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(4).cast::()); - - ErrorCode::_lift(l3 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Provide file advisory information on a descriptor. - /// - /// This is similar to `posix_fadvise` in POSIX. - pub fn advise( - &self, - offset: Filesize, - length: Filesize, - advice: Advice, - ) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.advise"] - fn wit_import(_: i32, _: i64, _: i64, _: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: i64, _: i32, _: *mut u8) { - unreachable!() - } - wit_import( - (self).handle() as i32, - _rt::as_i64(offset), - _rt::as_i64(length), - advice.clone() as i32, - ptr0, - ); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - ErrorCode::_lift(l2 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Synchronize the data of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fdatasync` in POSIX. - pub fn sync_data(&self) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.sync-data"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - ErrorCode::_lift(l2 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Get flags associated with a descriptor. - /// - /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. - /// - /// Note: This returns the value that was the `fs_flags` value returned - /// from `fdstat_get` in earlier versions of WASI. - pub fn get_flags(&self) -> Result { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.get-flags"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - DescriptorFlags::empty() - | DescriptorFlags::from_bits_retain(((l2 as u8) << 0) as _) - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(1).cast::()); - - ErrorCode::_lift(l3 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Get the dynamic type of a descriptor. - /// - /// Note: This returns the same value as the `type` field of the `fd-stat` - /// returned by `stat`, `stat-at` and similar. - /// - /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided - /// by `fstat` in POSIX. - /// - /// Note: This returns the value that was the `fs_filetype` value returned - /// from `fdstat_get` in earlier versions of WASI. - pub fn get_type(&self) -> Result { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.get-type"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - DescriptorType::_lift(l2 as u8) - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(1).cast::()); - - ErrorCode::_lift(l3 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Adjust the size of an open file. If this increases the file's size, the - /// extra bytes are filled with zeros. - /// - /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - pub fn set_size(&self, size: Filesize) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.set-size"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(size), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - ErrorCode::_lift(l2 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Adjust the timestamps of an open file or directory. - /// - /// Note: This is similar to `futimens` in POSIX. - /// - /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - pub fn set_times( - &self, - data_access_timestamp: NewTimestamp, - data_modification_timestamp: NewTimestamp, - ) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let (result1_0, result1_1, result1_2) = match data_access_timestamp { - NewTimestamp::NoChange => (0i32, 0i64, 0i32), - NewTimestamp::Now => (1i32, 0i64, 0i32), - NewTimestamp::Timestamp(e) => { - let super::super::super::wasi::clocks::wall_clock::Datetime { - seconds: seconds0, - nanoseconds: nanoseconds0, - } = e; - - (2i32, _rt::as_i64(seconds0), _rt::as_i32(nanoseconds0)) - } - }; - let (result3_0, result3_1, result3_2) = match data_modification_timestamp { - NewTimestamp::NoChange => (0i32, 0i64, 0i32), - NewTimestamp::Now => (1i32, 0i64, 0i32), - NewTimestamp::Timestamp(e) => { - let super::super::super::wasi::clocks::wall_clock::Datetime { - seconds: seconds2, - nanoseconds: nanoseconds2, - } = e; - - (2i32, _rt::as_i64(seconds2), _rt::as_i32(nanoseconds2)) - } - }; - let ptr4 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.set-times"] - fn wit_import( - _: i32, - _: i32, - _: i64, - _: i32, - _: i32, - _: i64, - _: i32, - _: *mut u8, - ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import( - _: i32, - _: i32, - _: i64, - _: i32, - _: i32, - _: i64, - _: i32, - _: *mut u8, - ) { - unreachable!() - } - wit_import( - (self).handle() as i32, - result1_0, - result1_1, - result1_2, - result3_0, - result3_1, - result3_2, - ptr4, - ); - let l5 = i32::from(*ptr4.add(0).cast::()); - match l5 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l6 = i32::from(*ptr4.add(1).cast::()); - - ErrorCode::_lift(l6 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Read from a descriptor, without using and updating the descriptor's offset. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// file was reached. The returned list will contain up to `length` bytes; it - /// may return fewer than requested, if the end of the file is reached or - /// if the I/O operation is interrupted. - /// - /// In the future, this may change to return a `stream`. - /// - /// Note: This is similar to `pread` in POSIX. - pub fn read( - &self, - length: Filesize, - offset: Filesize, - ) -> Result<(_rt::Vec, bool), ErrorCode> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.read"] - fn wit_import(_: i32, _: i64, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: i64, _: *mut u8) { - unreachable!() - } - wit_import( - (self).handle() as i32, - _rt::as_i64(length), - _rt::as_i64(offset), - ptr0, - ); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::<*mut u8>(); - let l3 = *ptr0.add(8).cast::(); - let len4 = l3; - let l5 = i32::from(*ptr0.add(12).cast::()); - - ( - _rt::Vec::from_raw_parts(l2.cast(), len4, len4), - _rt::bool_lift(l5 as u8), - ) - }; - Ok(e) - } - 1 => { - let e = { - let l6 = i32::from(*ptr0.add(4).cast::()); - - ErrorCode::_lift(l6 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Write to a descriptor, without using and updating the descriptor's offset. - /// - /// It is valid to write past the end of a file; the file is extended to the - /// extent of the write, with bytes between the previous end and the start of - /// the write set to zero. - /// - /// In the future, this may change to take a `stream`. - /// - /// Note: This is similar to `pwrite` in POSIX. - pub fn write( - &self, - buffer: &[u8], - offset: Filesize, - ) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let vec0 = buffer; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let ptr1 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.write"] - fn wit_import(_: i32, _: *mut u8, _: usize, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8, _: usize, _: i64, _: *mut u8) { - unreachable!() - } - wit_import( - (self).handle() as i32, - ptr0.cast_mut(), - len0, - _rt::as_i64(offset), - ptr1, - ); - let l2 = i32::from(*ptr1.add(0).cast::()); - match l2 { - 0 => { - let e = { - let l3 = *ptr1.add(8).cast::(); - - l3 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l4 = i32::from(*ptr1.add(8).cast::()); - - ErrorCode::_lift(l4 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Read directory entries from a directory. - /// - /// On filesystems where directories contain entries referring to themselves - /// and their parents, often named `.` and `..` respectively, these entries - /// are omitted. - /// - /// This always returns a new stream which starts at the beginning of the - /// directory. Multiple streams may be active on the same directory, and they - /// do not interfere with each other. - pub fn read_directory(&self) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.read-directory"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - - DirectoryEntryStream::from_handle(l2 as u32) - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(4).cast::()); - - ErrorCode::_lift(l3 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Synchronize the data and metadata of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fsync` in POSIX. - pub fn sync(&self) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.sync"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - ErrorCode::_lift(l2 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Create a directory. - /// - /// Note: This is similar to `mkdirat` in POSIX. - pub fn create_directory_at(&self, path: &str) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let vec0 = path; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let ptr1 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.create-directory-at"] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0.cast_mut(), len0, ptr1); - let l2 = i32::from(*ptr1.add(0).cast::()); - match l2 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr1.add(1).cast::()); - - ErrorCode::_lift(l3 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Return the attributes of an open file or directory. - /// - /// Note: This is similar to `fstat` in POSIX, except that it does not return - /// device and inode information. For testing whether two descriptors refer to - /// the same underlying filesystem object, use `is-same-object`. To obtain - /// additional data that can be used do determine whether a file has been - /// modified, use `metadata-hash`. - /// - /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - pub fn stat(&self) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 104]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 104]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.stat"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(8).cast::()); - let l3 = *ptr0.add(16).cast::(); - let l4 = *ptr0.add(24).cast::(); - let l5 = i32::from(*ptr0.add(32).cast::()); - let l8 = i32::from(*ptr0.add(56).cast::()); - let l11 = i32::from(*ptr0.add(80).cast::()); - - DescriptorStat { - type_: DescriptorType::_lift(l2 as u8), - link_count: l3 as u64, - size: l4 as u64, - data_access_timestamp: match l5 { - 0 => None, - 1 => { - let e = { - let l6 = *ptr0.add(40).cast::(); - let l7 = *ptr0.add(48).cast::(); - - super::super::super::wasi::clocks::wall_clock::Datetime{ - seconds: l6 as u64, - nanoseconds: l7 as u32, - } - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - }, - data_modification_timestamp: match l8 { - 0 => None, - 1 => { - let e = { - let l9 = *ptr0.add(64).cast::(); - let l10 = *ptr0.add(72).cast::(); - - super::super::super::wasi::clocks::wall_clock::Datetime{ - seconds: l9 as u64, - nanoseconds: l10 as u32, - } - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - }, - status_change_timestamp: match l11 { - 0 => None, - 1 => { - let e = { - let l12 = *ptr0.add(88).cast::(); - let l13 = *ptr0.add(96).cast::(); - - super::super::super::wasi::clocks::wall_clock::Datetime{ - seconds: l12 as u64, - nanoseconds: l13 as u32, - } - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - }, - } - }; - Ok(e) - } - 1 => { - let e = { - let l14 = i32::from(*ptr0.add(8).cast::()); - - ErrorCode::_lift(l14 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Return the attributes of a file or directory. - /// - /// Note: This is similar to `fstatat` in POSIX, except that it does not - /// return device and inode information. See the `stat` description for a - /// discussion of alternatives. - /// - /// Note: This was called `path_filestat_get` in earlier versions of WASI. - pub fn stat_at( - &self, - path_flags: PathFlags, - path: &str, - ) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 104]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 104]); - let flags0 = path_flags; - let vec1 = path; - let ptr1 = vec1.as_ptr().cast::(); - let len1 = vec1.len(); - let ptr2 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.stat-at"] - fn wit_import(_: i32, _: i32, _: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i32, _: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import( - (self).handle() as i32, - (flags0.bits() >> 0) as i32, - ptr1.cast_mut(), - len1, - ptr2, - ); - let l3 = i32::from(*ptr2.add(0).cast::()); - match l3 { - 0 => { - let e = { - let l4 = i32::from(*ptr2.add(8).cast::()); - let l5 = *ptr2.add(16).cast::(); - let l6 = *ptr2.add(24).cast::(); - let l7 = i32::from(*ptr2.add(32).cast::()); - let l10 = i32::from(*ptr2.add(56).cast::()); - let l13 = i32::from(*ptr2.add(80).cast::()); - - DescriptorStat { - type_: DescriptorType::_lift(l4 as u8), - link_count: l5 as u64, - size: l6 as u64, - data_access_timestamp: match l7 { - 0 => None, - 1 => { - let e = { - let l8 = *ptr2.add(40).cast::(); - let l9 = *ptr2.add(48).cast::(); - - super::super::super::wasi::clocks::wall_clock::Datetime{ - seconds: l8 as u64, - nanoseconds: l9 as u32, - } - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - }, - data_modification_timestamp: match l10 { - 0 => None, - 1 => { - let e = { - let l11 = *ptr2.add(64).cast::(); - let l12 = *ptr2.add(72).cast::(); - - super::super::super::wasi::clocks::wall_clock::Datetime{ - seconds: l11 as u64, - nanoseconds: l12 as u32, - } - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - }, - status_change_timestamp: match l13 { - 0 => None, - 1 => { - let e = { - let l14 = *ptr2.add(88).cast::(); - let l15 = *ptr2.add(96).cast::(); - - super::super::super::wasi::clocks::wall_clock::Datetime{ - seconds: l14 as u64, - nanoseconds: l15 as u32, - } - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - }, - } - }; - Ok(e) - } - 1 => { - let e = { - let l16 = i32::from(*ptr2.add(8).cast::()); - - ErrorCode::_lift(l16 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Adjust the timestamps of a file or directory. - /// - /// Note: This is similar to `utimensat` in POSIX. - /// - /// Note: This was called `path_filestat_set_times` in earlier versions of - /// WASI. - pub fn set_times_at( - &self, - path_flags: PathFlags, - path: &str, - data_access_timestamp: NewTimestamp, - data_modification_timestamp: NewTimestamp, - ) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let flags0 = path_flags; - let vec1 = path; - let ptr1 = vec1.as_ptr().cast::(); - let len1 = vec1.len(); - let (result3_0, result3_1, result3_2) = match data_access_timestamp { - NewTimestamp::NoChange => (0i32, 0i64, 0i32), - NewTimestamp::Now => (1i32, 0i64, 0i32), - NewTimestamp::Timestamp(e) => { - let super::super::super::wasi::clocks::wall_clock::Datetime { - seconds: seconds2, - nanoseconds: nanoseconds2, - } = e; - - (2i32, _rt::as_i64(seconds2), _rt::as_i32(nanoseconds2)) - } - }; - let (result5_0, result5_1, result5_2) = match data_modification_timestamp { - NewTimestamp::NoChange => (0i32, 0i64, 0i32), - NewTimestamp::Now => (1i32, 0i64, 0i32), - NewTimestamp::Timestamp(e) => { - let super::super::super::wasi::clocks::wall_clock::Datetime { - seconds: seconds4, - nanoseconds: nanoseconds4, - } = e; - - (2i32, _rt::as_i64(seconds4), _rt::as_i32(nanoseconds4)) - } - }; - let ptr6 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.set-times-at"] - fn wit_import( - _: i32, - _: i32, - _: *mut u8, - _: usize, - _: i32, - _: i64, - _: i32, - _: i32, - _: i64, - _: i32, - _: *mut u8, - ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import( - _: i32, - _: i32, - _: *mut u8, - _: usize, - _: i32, - _: i64, - _: i32, - _: i32, - _: i64, - _: i32, - _: *mut u8, - ) { - unreachable!() - } - wit_import( - (self).handle() as i32, - (flags0.bits() >> 0) as i32, - ptr1.cast_mut(), - len1, - result3_0, - result3_1, - result3_2, - result5_0, - result5_1, - result5_2, - ptr6, - ); - let l7 = i32::from(*ptr6.add(0).cast::()); - match l7 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l8 = i32::from(*ptr6.add(1).cast::()); - - ErrorCode::_lift(l8 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Create a hard link. - /// - /// Note: This is similar to `linkat` in POSIX. - pub fn link_at( - &self, - old_path_flags: PathFlags, - old_path: &str, - new_descriptor: &Descriptor, - new_path: &str, - ) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let flags0 = old_path_flags; - let vec1 = old_path; - let ptr1 = vec1.as_ptr().cast::(); - let len1 = vec1.len(); - let vec2 = new_path; - let ptr2 = vec2.as_ptr().cast::(); - let len2 = vec2.len(); - let ptr3 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.link-at"] - fn wit_import( - _: i32, - _: i32, - _: *mut u8, - _: usize, - _: i32, - _: *mut u8, - _: usize, - _: *mut u8, - ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import( - _: i32, - _: i32, - _: *mut u8, - _: usize, - _: i32, - _: *mut u8, - _: usize, - _: *mut u8, - ) { - unreachable!() - } - wit_import( - (self).handle() as i32, - (flags0.bits() >> 0) as i32, - ptr1.cast_mut(), - len1, - (new_descriptor).handle() as i32, - ptr2.cast_mut(), - len2, - ptr3, - ); - let l4 = i32::from(*ptr3.add(0).cast::()); - match l4 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l5 = i32::from(*ptr3.add(1).cast::()); - - ErrorCode::_lift(l5 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Open a file or directory. - /// - /// The returned descriptor is not guaranteed to be the lowest-numbered - /// descriptor not currently open/ it is randomized to prevent applications - /// from depending on making assumptions about indexes, since this is - /// error-prone in multi-threaded contexts. The returned descriptor is - /// guaranteed to be less than 2**31. - /// - /// If `flags` contains `descriptor-flags::mutate-directory`, and the base - /// descriptor doesn't have `descriptor-flags::mutate-directory` set, - /// `open-at` fails with `error-code::read-only`. - /// - /// If `flags` contains `write` or `mutate-directory`, or `open-flags` - /// contains `truncate` or `create`, and the base descriptor doesn't have - /// `descriptor-flags::mutate-directory` set, `open-at` fails with - /// `error-code::read-only`. - /// - /// Note: This is similar to `openat` in POSIX. - pub fn open_at( - &self, - path_flags: PathFlags, - path: &str, - open_flags: OpenFlags, - flags: DescriptorFlags, - ) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let flags0 = path_flags; - let vec1 = path; - let ptr1 = vec1.as_ptr().cast::(); - let len1 = vec1.len(); - let flags2 = open_flags; - let flags3 = flags; - let ptr4 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.open-at"] - fn wit_import( - _: i32, - _: i32, - _: *mut u8, - _: usize, - _: i32, - _: i32, - _: *mut u8, - ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import( - _: i32, - _: i32, - _: *mut u8, - _: usize, - _: i32, - _: i32, - _: *mut u8, - ) { - unreachable!() - } - wit_import( - (self).handle() as i32, - (flags0.bits() >> 0) as i32, - ptr1.cast_mut(), - len1, - (flags2.bits() >> 0) as i32, - (flags3.bits() >> 0) as i32, - ptr4, - ); - let l5 = i32::from(*ptr4.add(0).cast::()); - match l5 { - 0 => { - let e = { - let l6 = *ptr4.add(4).cast::(); - - Descriptor::from_handle(l6 as u32) - }; - Ok(e) - } - 1 => { - let e = { - let l7 = i32::from(*ptr4.add(4).cast::()); - - ErrorCode::_lift(l7 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Read the contents of a symbolic link. - /// - /// If the contents contain an absolute or rooted path in the underlying - /// filesystem, this function fails with `error-code::not-permitted`. - /// - /// Note: This is similar to `readlinkat` in POSIX. - pub fn readlink_at(&self, path: &str) -> Result<_rt::String, ErrorCode> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let vec0 = path; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let ptr1 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.readlink-at"] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0.cast_mut(), len0, ptr1); - let l2 = i32::from(*ptr1.add(0).cast::()); - match l2 { - 0 => { - let e = { - let l3 = *ptr1.add(4).cast::<*mut u8>(); - let l4 = *ptr1.add(8).cast::(); - let len5 = l4; - let bytes5 = _rt::Vec::from_raw_parts(l3.cast(), len5, len5); - - _rt::string_lift(bytes5) - }; - Ok(e) - } - 1 => { - let e = { - let l6 = i32::from(*ptr1.add(4).cast::()); - - ErrorCode::_lift(l6 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Remove a directory. - /// - /// Return `error-code::not-empty` if the directory is not empty. - /// - /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - pub fn remove_directory_at(&self, path: &str) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let vec0 = path; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let ptr1 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.remove-directory-at"] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0.cast_mut(), len0, ptr1); - let l2 = i32::from(*ptr1.add(0).cast::()); - match l2 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr1.add(1).cast::()); - - ErrorCode::_lift(l3 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Rename a filesystem object. - /// - /// Note: This is similar to `renameat` in POSIX. - pub fn rename_at( - &self, - old_path: &str, - new_descriptor: &Descriptor, - new_path: &str, - ) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let vec0 = old_path; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let vec1 = new_path; - let ptr1 = vec1.as_ptr().cast::(); - let len1 = vec1.len(); - let ptr2 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.rename-at"] - fn wit_import( - _: i32, - _: *mut u8, - _: usize, - _: i32, - _: *mut u8, - _: usize, - _: *mut u8, - ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import( - _: i32, - _: *mut u8, - _: usize, - _: i32, - _: *mut u8, - _: usize, - _: *mut u8, - ) { - unreachable!() - } - wit_import( - (self).handle() as i32, - ptr0.cast_mut(), - len0, - (new_descriptor).handle() as i32, - ptr1.cast_mut(), - len1, - ptr2, - ); - let l3 = i32::from(*ptr2.add(0).cast::()); - match l3 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l4 = i32::from(*ptr2.add(1).cast::()); - - ErrorCode::_lift(l4 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Create a symbolic link (also known as a "symlink"). - /// - /// If `old-path` starts with `/`, the function fails with - /// `error-code::not-permitted`. - /// - /// Note: This is similar to `symlinkat` in POSIX. - pub fn symlink_at(&self, old_path: &str, new_path: &str) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let vec0 = old_path; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let vec1 = new_path; - let ptr1 = vec1.as_ptr().cast::(); - let len1 = vec1.len(); - let ptr2 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.symlink-at"] - fn wit_import( - _: i32, - _: *mut u8, - _: usize, - _: *mut u8, - _: usize, - _: *mut u8, - ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import( - _: i32, - _: *mut u8, - _: usize, - _: *mut u8, - _: usize, - _: *mut u8, - ) { - unreachable!() - } - wit_import( - (self).handle() as i32, - ptr0.cast_mut(), - len0, - ptr1.cast_mut(), - len1, - ptr2, - ); - let l3 = i32::from(*ptr2.add(0).cast::()); - match l3 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l4 = i32::from(*ptr2.add(1).cast::()); - - ErrorCode::_lift(l4 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Unlink a filesystem object that is not a directory. - /// - /// Return `error-code::is-directory` if the path refers to a directory. - /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - pub fn unlink_file_at(&self, path: &str) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let vec0 = path; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let ptr1 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.unlink-file-at"] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0.cast_mut(), len0, ptr1); - let l2 = i32::from(*ptr1.add(0).cast::()); - match l2 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr1.add(1).cast::()); - - ErrorCode::_lift(l3 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Test whether two descriptors refer to the same filesystem object. - /// - /// In POSIX, this corresponds to testing whether the two descriptors have the - /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. - /// wasi-filesystem does not expose device and inode numbers, so this function - /// may be used instead. - pub fn is_same_object(&self, other: &Descriptor) -> bool { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.is-same-object"] - fn wit_import(_: i32, _: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32, (other).handle() as i32); - _rt::bool_lift(ret as u8) - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a descriptor. - /// - /// This returns a hash of the last-modification timestamp and file size, and - /// may also include the inode number, device number, birth timestamp, and - /// other metadata fields that may change when the file is modified or - /// replaced. It may also include a secret value chosen by the - /// implementation and not otherwise exposed. - /// - /// Implementations are encourated to provide the following properties: - /// - /// - If the file is not modified or replaced, the computed hash value should - /// usually not change. - /// - If the object is modified or replaced, the computed hash value should - /// usually change. - /// - The inputs to the hash should not be easily computable from the - /// computed hash. - /// - /// However, none of these is required. - pub fn metadata_hash(&self) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 24]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 24]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.metadata-hash"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - let l3 = *ptr0.add(16).cast::(); - - MetadataHashValue { - lower: l2 as u64, - upper: l3 as u64, - } - }; - Ok(e) - } - 1 => { - let e = { - let l4 = i32::from(*ptr0.add(8).cast::()); - - ErrorCode::_lift(l4 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl Descriptor { - #[allow(unused_unsafe, clippy::all)] - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a directory descriptor and a relative path. - /// - /// This performs the same hash computation as `metadata-hash`. - pub fn metadata_hash_at( - &self, - path_flags: PathFlags, - path: &str, - ) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 24]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 24]); - let flags0 = path_flags; - let vec1 = path; - let ptr1 = vec1.as_ptr().cast::(); - let len1 = vec1.len(); - let ptr2 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]descriptor.metadata-hash-at"] - fn wit_import(_: i32, _: i32, _: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i32, _: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import( - (self).handle() as i32, - (flags0.bits() >> 0) as i32, - ptr1.cast_mut(), - len1, - ptr2, - ); - let l3 = i32::from(*ptr2.add(0).cast::()); - match l3 { - 0 => { - let e = { - let l4 = *ptr2.add(8).cast::(); - let l5 = *ptr2.add(16).cast::(); - - MetadataHashValue { - lower: l4 as u64, - upper: l5 as u64, - } - }; - Ok(e) - } - 1 => { - let e = { - let l6 = i32::from(*ptr2.add(8).cast::()); - - ErrorCode::_lift(l6 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl DirectoryEntryStream { - #[allow(unused_unsafe, clippy::all)] - /// Read a single directory entry from a `directory-entry-stream`. - pub fn read_directory_entry(&self) -> Result, ErrorCode> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 20]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 20]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "[method]directory-entry-stream.read-directory-entry"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(4).cast::()); - - match l2 { - 0 => None, - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - let l4 = *ptr0.add(12).cast::<*mut u8>(); - let l5 = *ptr0.add(16).cast::(); - let len6 = l5; - let bytes6 = - _rt::Vec::from_raw_parts(l4.cast(), len6, len6); - - DirectoryEntry { - type_: DescriptorType::_lift(l3 as u8), - name: _rt::string_lift(bytes6), - } - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - } - }; - Ok(e) - } - 1 => { - let e = { - let l7 = i32::from(*ptr0.add(4).cast::()); - - ErrorCode::_lift(l7 as u8) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Attempts to extract a filesystem-related `error-code` from the stream - /// `error` provided. - /// - /// Stream operations which return `stream-error::last-operation-failed` - /// have a payload with more information about the operation that failed. - /// This payload can be passed through to this function to see if there's - /// filesystem-related information about the error to return. - /// - /// Note that this function is fallible because not all stream-related - /// errors are filesystem-related errors. - pub fn filesystem_error_code(err: &Error) -> Option { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/types@0.2.0")] - extern "C" { - #[link_name = "filesystem-error-code"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((err).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => None, - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - ErrorCode::_lift(l2 as u8) - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod preopens { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type Descriptor = super::super::super::wasi::filesystem::types::Descriptor; - #[allow(unused_unsafe, clippy::all)] - /// Return the set of preopened directories, and their path. - pub fn get_directories() -> _rt::Vec<(Descriptor, _rt::String)> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:filesystem/preopens@0.2.0")] - extern "C" { - #[link_name = "get-directories"] - fn wit_import(_: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8) { - unreachable!() - } - wit_import(ptr0); - let l1 = *ptr0.add(0).cast::<*mut u8>(); - let l2 = *ptr0.add(4).cast::(); - let base7 = l1; - let len7 = l2; - let mut result7 = _rt::Vec::with_capacity(len7); - for i in 0..len7 { - let base = base7.add(i * 12); - let e7 = { - let l3 = *base.add(0).cast::(); - let l4 = *base.add(4).cast::<*mut u8>(); - let l5 = *base.add(8).cast::(); - let len6 = l5; - let bytes6 = _rt::Vec::from_raw_parts(l4.cast(), len6, len6); - - (super::super::super::wasi::filesystem::types::Descriptor::from_handle(l3 as u32), _rt::string_lift(bytes6)) - }; - result7.push(e7); - } - _rt::cabi_dealloc(base7, len7 * 12, 4); - result7 - } - } - } - } - #[allow(dead_code)] - pub mod io { - #[allow(dead_code, clippy::all)] - pub mod error { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - /// A resource which represents some error information. - /// - /// The only method provided by this resource is `to-debug-string`, - /// which provides some human-readable information about the error. - /// - /// In the `wasi:io` package, this resource is returned through the - /// `wasi:io/streams/stream-error` type. - /// - /// To provide more specific error information, other interfaces may - /// provide functions to further "downcast" this error into more specific - /// error information. For example, `error`s returned in streams derived - /// from filesystem types to be described using the filesystem's own - /// error-code type, using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter - /// `borrow` and returns - /// `option`. - /// - /// The set of functions which can "downcast" an `error` into a more - /// concrete type is open. - - #[derive(Debug)] - #[repr(transparent)] - pub struct Error { - handle: _rt::Resource, - } - - impl Error { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for Error { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:io/error@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]error"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - impl Error { - #[allow(unused_unsafe, clippy::all)] - /// Returns a string that is suitable to assist humans in debugging - /// this error. - /// - /// WARNING: The returned string should not be consumed mechanically! - /// It may change across platforms, hosts, or other implementation - /// details. Parsing this string is a major platform-compatibility - /// hazard. - pub fn to_debug_string(&self) -> _rt::String { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/error@0.2.0")] - extern "C" { - #[link_name = "[method]error.to-debug-string"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = *ptr0.add(0).cast::<*mut u8>(); - let l2 = *ptr0.add(4).cast::(); - let len3 = l2; - let bytes3 = _rt::Vec::from_raw_parts(l1.cast(), len3, len3); - _rt::string_lift(bytes3) - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod poll { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - /// `pollable` represents a single I/O event which may be ready, or not. - - #[derive(Debug)] - #[repr(transparent)] - pub struct Pollable { - handle: _rt::Resource, - } - - impl Pollable { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for Pollable { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:io/poll@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]pollable"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - impl Pollable { - #[allow(unused_unsafe, clippy::all)] - /// Return the readiness of a pollable. This function never blocks. - /// - /// Returns `true` when the pollable is ready, and `false` otherwise. - pub fn ready(&self) -> bool { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/poll@0.2.0")] - extern "C" { - #[link_name = "[method]pollable.ready"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - _rt::bool_lift(ret as u8) - } - } - } - impl Pollable { - #[allow(unused_unsafe, clippy::all)] - /// `block` returns immediately if the pollable is ready, and otherwise - /// blocks until ready. - /// - /// This function is equivalent to calling `poll.poll` on a list - /// containing only this pollable. - pub fn block(&self) { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/poll@0.2.0")] - extern "C" { - #[link_name = "[method]pollable.block"] - fn wit_import(_: i32); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) { - unreachable!() - } - wit_import((self).handle() as i32); - } - } - } - #[allow(unused_unsafe, clippy::all)] - /// Poll for completion on a set of pollables. - /// - /// This function takes a list of pollables, which identify I/O sources of - /// interest, and waits until one or more of the events is ready for I/O. - /// - /// The result `list` contains one or more indices of handles in the - /// argument list that is ready for I/O. - /// - /// If the list contains more elements than can be indexed with a `u32` - /// value, this function traps. - /// - /// A timeout can be implemented by adding a pollable from the - /// wasi-clocks API to the list. - /// - /// This function does not return a `result`; polling in itself does not - /// do any I/O so it doesn't fail. If any of the I/O sources identified by - /// the pollables has an error, it is indicated by marking the source as - /// being reaedy for I/O. - pub fn poll(in_: &[&Pollable]) -> _rt::Vec { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let vec0 = in_; - let len0 = vec0.len(); - let layout0 = _rt::alloc::Layout::from_size_align_unchecked(vec0.len() * 4, 4); - let result0 = if layout0.size() != 0 { - let ptr = _rt::alloc::alloc(layout0).cast::(); - if ptr.is_null() { - _rt::alloc::handle_alloc_error(layout0); - } - ptr - } else { - { - ::core::ptr::null_mut() - } - }; - for (i, e) in vec0.into_iter().enumerate() { - let base = result0.add(i * 4); - { - *base.add(0).cast::() = (e).handle() as i32; - } - } - let ptr1 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/poll@0.2.0")] - extern "C" { - #[link_name = "poll"] - fn wit_import(_: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import(result0, len0, ptr1); - let l2 = *ptr1.add(0).cast::<*mut u8>(); - let l3 = *ptr1.add(4).cast::(); - let len4 = l3; - if layout0.size() != 0 { - _rt::alloc::dealloc(result0.cast(), layout0); - } - _rt::Vec::from_raw_parts(l2.cast(), len4, len4) - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod streams { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type Error = super::super::super::wasi::io::error::Error; - pub type Pollable = super::super::super::wasi::io::poll::Pollable; - /// An error for input-stream and output-stream operations. - pub enum StreamError { - /// The last operation (a write or flush) failed before completion. - /// - /// More information is available in the `error` payload. - LastOperationFailed(Error), - /// The stream is closed: no more input will be accepted by the - /// stream. A closed output-stream will return this error on all - /// future operations. - Closed, - } - impl ::core::fmt::Debug for StreamError { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - StreamError::LastOperationFailed(e) => f - .debug_tuple("StreamError::LastOperationFailed") - .field(e) - .finish(), - StreamError::Closed => f.debug_tuple("StreamError::Closed").finish(), - } - } - } - impl ::core::fmt::Display for StreamError { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write!(f, "{:?}", self) - } - } - - impl std::error::Error for StreamError {} - /// An input bytestream. - /// - /// `input-stream`s are *non-blocking* to the extent practical on underlying - /// platforms. I/O operations always return promptly; if fewer bytes are - /// promptly available than requested, they return the number of bytes promptly - /// available, which could even be zero. To wait for data to be available, - /// use the `subscribe` function to obtain a `pollable` which can be polled - /// for using `wasi:io/poll`. - - #[derive(Debug)] - #[repr(transparent)] - pub struct InputStream { - handle: _rt::Resource, - } - - impl InputStream { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for InputStream { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]input-stream"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - /// An output bytestream. - /// - /// `output-stream`s are *non-blocking* to the extent practical on - /// underlying platforms. Except where specified otherwise, I/O operations also - /// always return promptly, after the number of bytes that can be written - /// promptly, which could even be zero. To wait for the stream to be ready to - /// accept data, the `subscribe` function to obtain a `pollable` which can be - /// polled for using `wasi:io/poll`. - - #[derive(Debug)] - #[repr(transparent)] - pub struct OutputStream { - handle: _rt::Resource, - } - - impl OutputStream { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for OutputStream { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]output-stream"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - impl InputStream { - #[allow(unused_unsafe, clippy::all)] - /// Perform a non-blocking read from the stream. - /// - /// When the source of a `read` is binary data, the bytes from the source - /// are returned verbatim. When the source of a `read` is known to the - /// implementation to be text, bytes containing the UTF-8 encoding of the - /// text are returned. - /// - /// This function returns a list of bytes containing the read data, - /// when successful. The returned list will contain up to `len` bytes; - /// it may return fewer than requested, but not more. The list is - /// empty when no bytes are available for reading at this time. The - /// pollable given by `subscribe` will be ready when more bytes are - /// available. - /// - /// This function fails with a `stream-error` when the operation - /// encounters an error, giving `last-operation-failed`, or when the - /// stream is closed, giving `closed`. - /// - /// When the caller gives a `len` of 0, it represents a request to - /// read 0 bytes. If the stream is still open, this call should - /// succeed and return an empty list, or otherwise fail with `closed`. - /// - /// The `len` parameter is a `u64`, which could represent a list of u8 which - /// is not possible to allocate in wasm32, or not desirable to allocate as - /// as a return value by the callee. The callee may return a list of bytes - /// less than `len` in size while more bytes are available for reading. - pub fn read(&self, len: u64) -> Result<_rt::Vec, StreamError> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]input-stream.read"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&len), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::<*mut u8>(); - let l3 = *ptr0.add(8).cast::(); - let len4 = l3; - - _rt::Vec::from_raw_parts(l2.cast(), len4, len4) - }; - Ok(e) - } - 1 => { - let e = { - let l5 = i32::from(*ptr0.add(4).cast::()); - let v7 = match l5 { - 0 => { - let e7 = { - let l6 = *ptr0.add(8).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l6 as u32) - }; - StreamError::LastOperationFailed(e7) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v7 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl InputStream { - #[allow(unused_unsafe, clippy::all)] - /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, behavior is identical to `read`. - pub fn blocking_read(&self, len: u64) -> Result<_rt::Vec, StreamError> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]input-stream.blocking-read"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&len), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::<*mut u8>(); - let l3 = *ptr0.add(8).cast::(); - let len4 = l3; - - _rt::Vec::from_raw_parts(l2.cast(), len4, len4) - }; - Ok(e) - } - 1 => { - let e = { - let l5 = i32::from(*ptr0.add(4).cast::()); - let v7 = match l5 { - 0 => { - let e7 = { - let l6 = *ptr0.add(8).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l6 as u32) - }; - StreamError::LastOperationFailed(e7) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v7 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl InputStream { - #[allow(unused_unsafe, clippy::all)] - /// Skip bytes from a stream. Returns number of bytes skipped. - /// - /// Behaves identical to `read`, except instead of returning a list - /// of bytes, returns the number of bytes consumed from the stream. - pub fn skip(&self, len: u64) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]input-stream.skip"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&len), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - let v5 = match l3 { - 0 => { - let e5 = { - let l4 = *ptr0.add(12).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l4 as u32) - }; - StreamError::LastOperationFailed(e5) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v5 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl InputStream { - #[allow(unused_unsafe, clippy::all)] - /// Skip bytes from a stream, after blocking until at least one byte - /// can be skipped. Except for blocking behavior, identical to `skip`. - pub fn blocking_skip(&self, len: u64) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]input-stream.blocking-skip"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&len), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - let v5 = match l3 { - 0 => { - let e5 = { - let l4 = *ptr0.add(12).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l4 as u32) - }; - StreamError::LastOperationFailed(e5) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v5 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl InputStream { - #[allow(unused_unsafe, clippy::all)] - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - /// The created `pollable` is a child resource of the `input-stream`. - /// Implementations may trap if the `input-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - pub fn subscribe(&self) -> Pollable { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]input-stream.subscribe"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - super::super::super::wasi::io::poll::Pollable::from_handle(ret as u32) - } - } - } - impl OutputStream { - #[allow(unused_unsafe, clippy::all)] - /// Check readiness for writing. This function never blocks. - /// - /// Returns the number of bytes permitted for the next call to `write`, - /// or an error. Calling `write` with more bytes than this function has - /// permitted will trap. - /// - /// When this function returns 0 bytes, the `subscribe` pollable will - /// become ready when this function will report at least 1 byte, or an - /// error. - pub fn check_write(&self) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]output-stream.check-write"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - let v5 = match l3 { - 0 => { - let e5 = { - let l4 = *ptr0.add(12).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l4 as u32) - }; - StreamError::LastOperationFailed(e5) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v5 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl OutputStream { - #[allow(unused_unsafe, clippy::all)] - /// Perform a write. This function never blocks. - /// - /// When the destination of a `write` is binary data, the bytes from - /// `contents` are written verbatim. When the destination of a `write` is - /// known to the implementation to be text, the bytes of `contents` are - /// transcoded from UTF-8 into the encoding of the destination and then - /// written. - /// - /// Precondition: check-write gave permit of Ok(n) and contents has a - /// length of less than or equal to n. Otherwise, this function will trap. - /// - /// returns Err(closed) without writing if the stream has closed since - /// the last call to check-write provided a permit. - pub fn write(&self, contents: &[u8]) -> Result<(), StreamError> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let vec0 = contents; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let ptr1 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]output-stream.write"] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0.cast_mut(), len0, ptr1); - let l2 = i32::from(*ptr1.add(0).cast::()); - match l2 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr1.add(4).cast::()); - let v5 = match l3 { - 0 => { - let e5 = { - let l4 = *ptr1.add(8).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l4 as u32) - }; - StreamError::LastOperationFailed(e5) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v5 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl OutputStream { - #[allow(unused_unsafe, clippy::all)] - /// Perform a write of up to 4096 bytes, and then flush the stream. Block - /// until all of these operations are complete, or an error occurs. - /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write`, and `flush`, and is implemented with the - /// following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while !contents.is_empty() { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, contents.len()); - /// let (chunk, rest) = contents.split_at(len); - /// this.write(chunk ); // eliding error handling - /// contents = rest; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` - pub fn blocking_write_and_flush(&self, contents: &[u8]) -> Result<(), StreamError> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let vec0 = contents; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let ptr1 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]output-stream.blocking-write-and-flush"] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0.cast_mut(), len0, ptr1); - let l2 = i32::from(*ptr1.add(0).cast::()); - match l2 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr1.add(4).cast::()); - let v5 = match l3 { - 0 => { - let e5 = { - let l4 = *ptr1.add(8).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l4 as u32) - }; - StreamError::LastOperationFailed(e5) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v5 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl OutputStream { - #[allow(unused_unsafe, clippy::all)] - /// Request to flush buffered output. This function never blocks. - /// - /// This tells the output-stream that the caller intends any buffered - /// output to be flushed. the output which is expected to be flushed - /// is all that has been passed to `write` prior to this call. - /// - /// Upon calling this function, the `output-stream` will not accept any - /// writes (`check-write` will return `ok(0)`) until the flush has - /// completed. The `subscribe` pollable will become ready when the - /// flush has completed and the stream can accept more writes. - pub fn flush(&self) -> Result<(), StreamError> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]output-stream.flush"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(4).cast::()); - let v4 = match l2 { - 0 => { - let e4 = { - let l3 = *ptr0.add(8).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l3 as u32) - }; - StreamError::LastOperationFailed(e4) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v4 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl OutputStream { - #[allow(unused_unsafe, clippy::all)] - /// Request to flush buffered output, and block until flush completes - /// and stream is ready for writing again. - pub fn blocking_flush(&self) -> Result<(), StreamError> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]output-stream.blocking-flush"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(4).cast::()); - let v4 = match l2 { - 0 => { - let e4 = { - let l3 = *ptr0.add(8).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l3 as u32) - }; - StreamError::LastOperationFailed(e4) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v4 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl OutputStream { - #[allow(unused_unsafe, clippy::all)] - /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occured. When this - /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an - /// error. - /// - /// If the stream is closed, this pollable is always ready immediately. - /// - /// The created `pollable` is a child resource of the `output-stream`. - /// Implementations may trap if the `output-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - pub fn subscribe(&self) -> Pollable { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]output-stream.subscribe"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - super::super::super::wasi::io::poll::Pollable::from_handle(ret as u32) - } - } - } - impl OutputStream { - #[allow(unused_unsafe, clippy::all)] - /// Write zeroes to a stream. - /// - /// This should be used precisely like `write` with the exact same - /// preconditions (must use check-write first), but instead of - /// passing a list of bytes, you simply pass the number of zero-bytes - /// that should be written. - pub fn write_zeroes(&self, len: u64) -> Result<(), StreamError> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]output-stream.write-zeroes"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&len), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(4).cast::()); - let v4 = match l2 { - 0 => { - let e4 = { - let l3 = *ptr0.add(8).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l3 as u32) - }; - StreamError::LastOperationFailed(e4) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v4 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl OutputStream { - #[allow(unused_unsafe, clippy::all)] - /// Perform a write of up to 4096 zeroes, and then flush the stream. - /// Block until all of these operations are complete, or an error - /// occurs. - /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with - /// the following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while num_zeroes != 0 { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, num_zeroes); - /// this.write-zeroes(len); // eliding error handling - /// num_zeroes -= len; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` - pub fn blocking_write_zeroes_and_flush(&self, len: u64) -> Result<(), StreamError> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]output-stream.blocking-write-zeroes-and-flush"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&len), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(4).cast::()); - let v4 = match l2 { - 0 => { - let e4 = { - let l3 = *ptr0.add(8).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l3 as u32) - }; - StreamError::LastOperationFailed(e4) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v4 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl OutputStream { - #[allow(unused_unsafe, clippy::all)] - /// Read from one stream and write to another. - /// - /// The behavior of splice is equivelant to: - /// 1. calling `check-write` on the `output-stream` - /// 2. calling `read` on the `input-stream` with the smaller of the - /// `check-write` permitted length and the `len` provided to `splice` - /// 3. calling `write` on the `output-stream` with that read data. - /// - /// Any error reported by the call to `check-write`, `read`, or - /// `write` ends the splice and reports that error. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - pub fn splice(&self, src: &InputStream, len: u64) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]output-stream.splice"] - fn wit_import(_: i32, _: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import( - (self).handle() as i32, - (src).handle() as i32, - _rt::as_i64(&len), - ptr0, - ); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - let v5 = match l3 { - 0 => { - let e5 = { - let l4 = *ptr0.add(12).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l4 as u32) - }; - StreamError::LastOperationFailed(e5) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v5 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl OutputStream { - #[allow(unused_unsafe, clippy::all)] - /// Read from one stream and write to another, with blocking. - /// - /// This is similar to `splice`, except that it blocks until the - /// `output-stream` is ready for writing, and the `input-stream` - /// is ready for reading, before performing the `splice`. - pub fn blocking_splice( - &self, - src: &InputStream, - len: u64, - ) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:io/streams@0.2.0")] - extern "C" { - #[link_name = "[method]output-stream.blocking-splice"] - fn wit_import(_: i32, _: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import( - (self).handle() as i32, - (src).handle() as i32, - _rt::as_i64(&len), - ptr0, - ); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - let v5 = match l3 { - 0 => { - let e5 = { - let l4 = *ptr0.add(12).cast::(); - - super::super::super::wasi::io::error::Error::from_handle(l4 as u32) - }; - StreamError::LastOperationFailed(e5) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - StreamError::Closed - } - }; - - v5 - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - } - } - #[allow(dead_code)] - pub mod random { - #[allow(dead_code, clippy::all)] - pub mod random { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - #[allow(unused_unsafe, clippy::all)] - /// Return `len` cryptographically-secure random or pseudo-random bytes. - /// - /// This function must produce data at least as cryptographically secure and - /// fast as an adequately seeded cryptographically-secure pseudo-random - /// number generator (CSPRNG). It must not block, from the perspective of - /// the calling program, under any circumstances, including on the first - /// request and on requests for numbers of bytes. The returned data must - /// always be unpredictable. - /// - /// This function must always return fresh data. Deterministic environments - /// must omit this function, rather than implementing it with deterministic - /// data. - pub fn get_random_bytes(len: u64) -> _rt::Vec { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:random/random@0.2.0")] - extern "C" { - #[link_name = "get-random-bytes"] - fn wit_import(_: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: *mut u8) { - unreachable!() - } - wit_import(_rt::as_i64(&len), ptr0); - let l1 = *ptr0.add(0).cast::<*mut u8>(); - let l2 = *ptr0.add(4).cast::(); - let len3 = l2; - _rt::Vec::from_raw_parts(l1.cast(), len3, len3) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Return a cryptographically-secure random or pseudo-random `u64` value. - /// - /// This function returns the same type of data as `get-random-bytes`, - /// represented as a `u64`. - pub fn get_random_u64() -> u64 { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:random/random@0.2.0")] - extern "C" { - #[link_name = "get-random-u64"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64 { - unreachable!() - } - let ret = wit_import(); - ret as u64 - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod insecure { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - #[allow(unused_unsafe, clippy::all)] - /// Return `len` insecure pseudo-random bytes. - /// - /// This function is not cryptographically secure. Do not use it for - /// anything related to security. - /// - /// There are no requirements on the values of the returned bytes, however - /// implementations are encouraged to return evenly distributed values with - /// a long period. - pub fn get_insecure_random_bytes(len: u64) -> _rt::Vec { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:random/insecure@0.2.0")] - extern "C" { - #[link_name = "get-insecure-random-bytes"] - fn wit_import(_: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i64, _: *mut u8) { - unreachable!() - } - wit_import(_rt::as_i64(&len), ptr0); - let l1 = *ptr0.add(0).cast::<*mut u8>(); - let l2 = *ptr0.add(4).cast::(); - let len3 = l2; - _rt::Vec::from_raw_parts(l1.cast(), len3, len3) - } - } - #[allow(unused_unsafe, clippy::all)] - /// Return an insecure pseudo-random `u64` value. - /// - /// This function returns the same type of pseudo-random data as - /// `get-insecure-random-bytes`, represented as a `u64`. - pub fn get_insecure_random_u64() -> u64 { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:random/insecure@0.2.0")] - extern "C" { - #[link_name = "get-insecure-random-u64"] - fn wit_import() -> i64; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i64 { - unreachable!() - } - let ret = wit_import(); - ret as u64 - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod insecure_seed { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - #[allow(unused_unsafe, clippy::all)] - /// Return a 128-bit value that may contain a pseudo-random value. - /// - /// The returned value is not required to be computed from a CSPRNG, and may - /// even be entirely deterministic. Host implementations are encouraged to - /// provide pseudo-random values to any program exposed to - /// attacker-controlled content, to enable DoS protection built into many - /// languages' hash-map implementations. - /// - /// This function is intended to only be called once, by a source language - /// to initialize Denial Of Service (DoS) protection in its hash-map - /// implementation. - /// - /// # Expected future evolution - /// - /// This will likely be changed to a value import, to prevent it from being - /// called multiple times and potentially used for purposes other than DoS - /// protection. - pub fn insecure_seed() -> (u64, u64) { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:random/insecure-seed@0.2.0")] - extern "C" { - #[link_name = "insecure-seed"] - fn wit_import(_: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: *mut u8) { - unreachable!() - } - wit_import(ptr0); - let l1 = *ptr0.add(0).cast::(); - let l2 = *ptr0.add(8).cast::(); - (l1 as u64, l2 as u64) - } - } - } - } - #[allow(dead_code)] - pub mod sockets { - #[allow(dead_code, clippy::all)] - pub mod network { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - /// An opaque resource that represents access to (a subset of) the network. - /// This enables context-based security for networking. - /// There is no need for this to map 1:1 to a physical network interface. - - #[derive(Debug)] - #[repr(transparent)] - pub struct Network { - handle: _rt::Resource, - } - - impl Network { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for Network { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:sockets/network@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]network"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - /// Error codes. - /// - /// In theory, every API can return any error code. - /// In practice, API's typically only return the errors documented per API - /// combined with a couple of errors that are always possible: - /// - `unknown` - /// - `access-denied` - /// - `not-supported` - /// - `out-of-memory` - /// - `concurrency-conflict` - /// - /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - #[repr(u8)] - #[derive(Clone, Copy, Eq, PartialEq)] - pub enum ErrorCode { - /// Unknown error - Unknown, - /// Access denied. - /// - /// POSIX equivalent: EACCES, EPERM - AccessDenied, - /// The operation is not supported. - /// - /// POSIX equivalent: EOPNOTSUPP - NotSupported, - /// One of the arguments is invalid. - /// - /// POSIX equivalent: EINVAL - InvalidArgument, - /// Not enough memory to complete the operation. - /// - /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY - OutOfMemory, - /// The operation timed out before it could finish completely. - Timeout, - /// This operation is incompatible with another asynchronous operation that is already in progress. - /// - /// POSIX equivalent: EALREADY - ConcurrencyConflict, - /// Trying to finish an asynchronous operation that: - /// - has not been started yet, or: - /// - was already finished by a previous `finish-*` call. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - NotInProgress, - /// The operation has been aborted because it could not be completed immediately. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - WouldBlock, - /// The operation is not valid in the socket's current state. - InvalidState, - /// A new socket resource could not be created because of a system limit. - NewSocketLimit, - /// A bind operation failed because the provided address is not an address that the `network` can bind to. - AddressNotBindable, - /// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available. - AddressInUse, - /// The remote address is not reachable - RemoteUnreachable, - /// The TCP connection was forcefully rejected - ConnectionRefused, - /// The TCP connection was reset. - ConnectionReset, - /// A TCP connection was aborted. - ConnectionAborted, - /// The size of a datagram sent to a UDP socket exceeded the maximum - /// supported size. - DatagramTooLarge, - /// Name does not exist or has no suitable associated IP addresses. - NameUnresolvable, - /// A temporary failure in name resolution occurred. - TemporaryResolverFailure, - /// A permanent failure in name resolution occurred. - PermanentResolverFailure, - } - impl ErrorCode { - pub fn name(&self) -> &'static str { - match self { - ErrorCode::Unknown => "unknown", - ErrorCode::AccessDenied => "access-denied", - ErrorCode::NotSupported => "not-supported", - ErrorCode::InvalidArgument => "invalid-argument", - ErrorCode::OutOfMemory => "out-of-memory", - ErrorCode::Timeout => "timeout", - ErrorCode::ConcurrencyConflict => "concurrency-conflict", - ErrorCode::NotInProgress => "not-in-progress", - ErrorCode::WouldBlock => "would-block", - ErrorCode::InvalidState => "invalid-state", - ErrorCode::NewSocketLimit => "new-socket-limit", - ErrorCode::AddressNotBindable => "address-not-bindable", - ErrorCode::AddressInUse => "address-in-use", - ErrorCode::RemoteUnreachable => "remote-unreachable", - ErrorCode::ConnectionRefused => "connection-refused", - ErrorCode::ConnectionReset => "connection-reset", - ErrorCode::ConnectionAborted => "connection-aborted", - ErrorCode::DatagramTooLarge => "datagram-too-large", - ErrorCode::NameUnresolvable => "name-unresolvable", - ErrorCode::TemporaryResolverFailure => "temporary-resolver-failure", - ErrorCode::PermanentResolverFailure => "permanent-resolver-failure", - } - } - pub fn message(&self) -> &'static str { - match self { - ErrorCode::Unknown => "Unknown error", - ErrorCode::AccessDenied => "Access denied. - - POSIX equivalent: EACCES, EPERM", - ErrorCode::NotSupported => "The operation is not supported. - - POSIX equivalent: EOPNOTSUPP", - ErrorCode::InvalidArgument => "One of the arguments is invalid. - - POSIX equivalent: EINVAL", - ErrorCode::OutOfMemory => "Not enough memory to complete the operation. - - POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY", - ErrorCode::Timeout => "The operation timed out before it could finish completely.", - ErrorCode::ConcurrencyConflict => "This operation is incompatible with another asynchronous operation that is already in progress. - - POSIX equivalent: EALREADY", - ErrorCode::NotInProgress => "Trying to finish an asynchronous operation that: - - has not been started yet, or: - - was already finished by a previous `finish-*` call. - - Note: this is scheduled to be removed when `future`s are natively supported.", - ErrorCode::WouldBlock => "The operation has been aborted because it could not be completed immediately. - - Note: this is scheduled to be removed when `future`s are natively supported.", - ErrorCode::InvalidState => "The operation is not valid in the socket's current state.", - ErrorCode::NewSocketLimit => "A new socket resource could not be created because of a system limit.", - ErrorCode::AddressNotBindable => "A bind operation failed because the provided address is not an address that the `network` can bind to.", - ErrorCode::AddressInUse => "A bind operation failed because the provided address is already in use or because there are no ephemeral ports available.", - ErrorCode::RemoteUnreachable => "The remote address is not reachable", - ErrorCode::ConnectionRefused => "The TCP connection was forcefully rejected", - ErrorCode::ConnectionReset => "The TCP connection was reset.", - ErrorCode::ConnectionAborted => "A TCP connection was aborted.", - ErrorCode::DatagramTooLarge => "The size of a datagram sent to a UDP socket exceeded the maximum - supported size.", - ErrorCode::NameUnresolvable => "Name does not exist or has no suitable associated IP addresses.", - ErrorCode::TemporaryResolverFailure => "A temporary failure in name resolution occurred.", - ErrorCode::PermanentResolverFailure => "A permanent failure in name resolution occurred.", - } - } - } - impl ::core::fmt::Debug for ErrorCode { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("ErrorCode") - .field("code", &(*self as i32)) - .field("name", &self.name()) - .field("message", &self.message()) - .finish() - } - } - impl ::core::fmt::Display for ErrorCode { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - write!(f, "{} (error {})", self.name(), *self as i32) - } - } - - impl std::error::Error for ErrorCode {} - - impl ErrorCode { - pub(crate) unsafe fn _lift(val: u8) -> ErrorCode { - if !cfg!(debug_assertions) { - return ::core::mem::transmute(val); - } - - match val { - 0 => ErrorCode::Unknown, - 1 => ErrorCode::AccessDenied, - 2 => ErrorCode::NotSupported, - 3 => ErrorCode::InvalidArgument, - 4 => ErrorCode::OutOfMemory, - 5 => ErrorCode::Timeout, - 6 => ErrorCode::ConcurrencyConflict, - 7 => ErrorCode::NotInProgress, - 8 => ErrorCode::WouldBlock, - 9 => ErrorCode::InvalidState, - 10 => ErrorCode::NewSocketLimit, - 11 => ErrorCode::AddressNotBindable, - 12 => ErrorCode::AddressInUse, - 13 => ErrorCode::RemoteUnreachable, - 14 => ErrorCode::ConnectionRefused, - 15 => ErrorCode::ConnectionReset, - 16 => ErrorCode::ConnectionAborted, - 17 => ErrorCode::DatagramTooLarge, - 18 => ErrorCode::NameUnresolvable, - 19 => ErrorCode::TemporaryResolverFailure, - 20 => ErrorCode::PermanentResolverFailure, - - _ => panic!("invalid enum discriminant"), - } - } - } - - #[repr(u8)] - #[derive(Clone, Copy, Eq, PartialEq)] - pub enum IpAddressFamily { - /// Similar to `AF_INET` in POSIX. - Ipv4, - /// Similar to `AF_INET6` in POSIX. - Ipv6, - } - impl ::core::fmt::Debug for IpAddressFamily { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - IpAddressFamily::Ipv4 => f.debug_tuple("IpAddressFamily::Ipv4").finish(), - IpAddressFamily::Ipv6 => f.debug_tuple("IpAddressFamily::Ipv6").finish(), - } - } - } - - impl IpAddressFamily { - pub(crate) unsafe fn _lift(val: u8) -> IpAddressFamily { - if !cfg!(debug_assertions) { - return ::core::mem::transmute(val); - } - - match val { - 0 => IpAddressFamily::Ipv4, - 1 => IpAddressFamily::Ipv6, - - _ => panic!("invalid enum discriminant"), - } - } - } - - pub type Ipv4Address = (u8, u8, u8, u8); - pub type Ipv6Address = (u16, u16, u16, u16, u16, u16, u16, u16); - #[derive(Clone, Copy)] - pub enum IpAddress { - Ipv4(Ipv4Address), - Ipv6(Ipv6Address), - } - impl ::core::fmt::Debug for IpAddress { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - IpAddress::Ipv4(e) => f.debug_tuple("IpAddress::Ipv4").field(e).finish(), - IpAddress::Ipv6(e) => f.debug_tuple("IpAddress::Ipv6").field(e).finish(), - } - } - } - #[repr(C)] - #[derive(Clone, Copy)] - pub struct Ipv4SocketAddress { - /// sin_port - pub port: u16, - /// sin_addr - pub address: Ipv4Address, - } - impl ::core::fmt::Debug for Ipv4SocketAddress { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Ipv4SocketAddress") - .field("port", &self.port) - .field("address", &self.address) - .finish() - } - } - #[repr(C)] - #[derive(Clone, Copy)] - pub struct Ipv6SocketAddress { - /// sin6_port - pub port: u16, - /// sin6_flowinfo - pub flow_info: u32, - /// sin6_addr - pub address: Ipv6Address, - /// sin6_scope_id - pub scope_id: u32, - } - impl ::core::fmt::Debug for Ipv6SocketAddress { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("Ipv6SocketAddress") - .field("port", &self.port) - .field("flow-info", &self.flow_info) - .field("address", &self.address) - .field("scope-id", &self.scope_id) - .finish() - } - } - #[derive(Clone, Copy)] - pub enum IpSocketAddress { - Ipv4(Ipv4SocketAddress), - Ipv6(Ipv6SocketAddress), - } - impl ::core::fmt::Debug for IpSocketAddress { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - IpSocketAddress::Ipv4(e) => { - f.debug_tuple("IpSocketAddress::Ipv4").field(e).finish() - } - IpSocketAddress::Ipv6(e) => { - f.debug_tuple("IpSocketAddress::Ipv6").field(e).finish() - } - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod instance_network { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - pub type Network = super::super::super::wasi::sockets::network::Network; - #[allow(unused_unsafe, clippy::all)] - /// Get a handle to the default network. - pub fn instance_network() -> Network { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/instance-network@0.2.0")] - extern "C" { - #[link_name = "instance-network"] - fn wit_import() -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import() -> i32 { - unreachable!() - } - let ret = wit_import(); - super::super::super::wasi::sockets::network::Network::from_handle(ret as u32) - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod udp { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type Pollable = super::super::super::wasi::io::poll::Pollable; - pub type Network = super::super::super::wasi::sockets::network::Network; - pub type ErrorCode = super::super::super::wasi::sockets::network::ErrorCode; - pub type IpSocketAddress = super::super::super::wasi::sockets::network::IpSocketAddress; - pub type IpAddressFamily = super::super::super::wasi::sockets::network::IpAddressFamily; - /// A received datagram. - #[derive(Clone)] - pub struct IncomingDatagram { - /// The payload. - /// - /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. - pub data: _rt::Vec, - /// The source address. - /// - /// This field is guaranteed to match the remote address the stream was initialized with, if any. - /// - /// Equivalent to the `src_addr` out parameter of `recvfrom`. - pub remote_address: IpSocketAddress, - } - impl ::core::fmt::Debug for IncomingDatagram { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("IncomingDatagram") - .field("data", &self.data) - .field("remote-address", &self.remote_address) - .finish() - } - } - /// A datagram to be sent out. - #[derive(Clone)] - pub struct OutgoingDatagram { - /// The payload. - pub data: _rt::Vec, - /// The destination address. - /// - /// The requirements on this field depend on how the stream was initialized: - /// - with a remote address: this field must be None or match the stream's remote address exactly. - /// - without a remote address: this field is required. - /// - /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. - pub remote_address: Option, - } - impl ::core::fmt::Debug for OutgoingDatagram { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - f.debug_struct("OutgoingDatagram") - .field("data", &self.data) - .field("remote-address", &self.remote_address) - .finish() - } - } - /// A UDP socket handle. - - #[derive(Debug)] - #[repr(transparent)] - pub struct UdpSocket { - handle: _rt::Resource, - } - - impl UdpSocket { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for UdpSocket { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]udp-socket"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - #[derive(Debug)] - #[repr(transparent)] - pub struct IncomingDatagramStream { - handle: _rt::Resource, - } - - impl IncomingDatagramStream { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for IncomingDatagramStream { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]incoming-datagram-stream"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - #[derive(Debug)] - #[repr(transparent)] - pub struct OutgoingDatagramStream { - handle: _rt::Resource, - } - - impl OutgoingDatagramStream { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for OutgoingDatagramStream { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]outgoing-datagram-stream"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the port is zero, the socket will be bound to a random free port. - /// - /// # Typical errors - /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) - /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// Unlike in POSIX, in WASI the bind operation is async. This enables - /// interactive WASI hosts to inject permission prompts. Runtimes that - /// don't want to make use of this ability can simply call the native - /// `bind` as part of either `start-bind` or `finish-bind`. - /// - /// # References - /// - - /// - - /// - - /// - - pub fn start_bind( - &self, - network: &Network, - local_address: IpSocketAddress, - ) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - use super::super::super::wasi::sockets::network::IpSocketAddress as V4; - let ( - result5_0, - result5_1, - result5_2, - result5_3, - result5_4, - result5_5, - result5_6, - result5_7, - result5_8, - result5_9, - result5_10, - result5_11, - ) = match local_address { - V4::Ipv4(e) => { - let super::super::super::wasi::sockets::network::Ipv4SocketAddress{ port:port0, address:address0, } = e; - let (t1_0, t1_1, t1_2, t1_3) = address0; - - ( - 0i32, - _rt::as_i32(port0), - _rt::as_i32(t1_0), - _rt::as_i32(t1_1), - _rt::as_i32(t1_2), - _rt::as_i32(t1_3), - 0i32, - 0i32, - 0i32, - 0i32, - 0i32, - 0i32, - ) - } - V4::Ipv6(e) => { - let super::super::super::wasi::sockets::network::Ipv6SocketAddress{ port:port2, flow_info:flow_info2, address:address2, scope_id:scope_id2, } = e; - let (t3_0, t3_1, t3_2, t3_3, t3_4, t3_5, t3_6, t3_7) = address2; - - ( - 1i32, - _rt::as_i32(port2), - _rt::as_i32(flow_info2), - _rt::as_i32(t3_0), - _rt::as_i32(t3_1), - _rt::as_i32(t3_2), - _rt::as_i32(t3_3), - _rt::as_i32(t3_4), - _rt::as_i32(t3_5), - _rt::as_i32(t3_6), - _rt::as_i32(t3_7), - _rt::as_i32(scope_id2), - ) - } - }; - let ptr6 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.start-bind"] - fn wit_import( - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: *mut u8, - ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import( - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: *mut u8, - ) { - unreachable!() - } - wit_import( - (self).handle() as i32, - (network).handle() as i32, - result5_0, - result5_1, - result5_2, - result5_3, - result5_4, - result5_5, - result5_6, - result5_7, - result5_8, - result5_9, - result5_10, - result5_11, - ptr6, - ); - let l7 = i32::from(*ptr6.add(0).cast::()); - match l7 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l8 = i32::from(*ptr6.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l8 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn finish_bind(&self) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.finish-bind"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Set up inbound & outbound communication channels, optionally to a specific peer. - /// - /// This function only changes the local socket configuration and does not generate any network traffic. - /// On success, the `remote-address` of the socket is updated. The `local-address` may be updated as well, - /// based on the best network path to `remote-address`. - /// - /// When a `remote-address` is provided, the returned streams are limited to communicating with that specific peer: - /// - `send` can only be used to send to this destination. - /// - `receive` will only return datagrams sent from the provided `remote-address`. - /// - /// This method may be called multiple times on the same socket to change its association, but - /// only the most recently returned pair of streams will be operational. Implementations may trap if - /// the streams returned by a previous invocation haven't been dropped yet before calling `stream` again. - /// - /// The POSIX equivalent in pseudo-code is: - /// ```text - /// if (was previously connected) { - /// connect(s, AF_UNSPEC) - /// } - /// if (remote_address is Some) { - /// connect(s, remote_address) - /// } - /// ``` - /// - /// Unlike in POSIX, the socket must already be explicitly bound. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-state`: The socket is not bound. - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - /// # References - /// - - /// - - /// - - /// - - pub fn stream( - &self, - remote_address: Option, - ) -> Result<(IncomingDatagramStream, OutgoingDatagramStream), ErrorCode> - { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let ( - result6_0, - result6_1, - result6_2, - result6_3, - result6_4, - result6_5, - result6_6, - result6_7, - result6_8, - result6_9, - result6_10, - result6_11, - result6_12, - ) = match remote_address { - Some(e) => { - use super::super::super::wasi::sockets::network::IpSocketAddress as V4; - let ( - result5_0, - result5_1, - result5_2, - result5_3, - result5_4, - result5_5, - result5_6, - result5_7, - result5_8, - result5_9, - result5_10, - result5_11, - ) = match e { - V4::Ipv4(e) => { - let super::super::super::wasi::sockets::network::Ipv4SocketAddress{ port:port0, address:address0, } = e; - let (t1_0, t1_1, t1_2, t1_3) = address0; - - ( - 0i32, - _rt::as_i32(port0), - _rt::as_i32(t1_0), - _rt::as_i32(t1_1), - _rt::as_i32(t1_2), - _rt::as_i32(t1_3), - 0i32, - 0i32, - 0i32, - 0i32, - 0i32, - 0i32, - ) - } - V4::Ipv6(e) => { - let super::super::super::wasi::sockets::network::Ipv6SocketAddress{ port:port2, flow_info:flow_info2, address:address2, scope_id:scope_id2, } = e; - let (t3_0, t3_1, t3_2, t3_3, t3_4, t3_5, t3_6, t3_7) = - address2; - - ( - 1i32, - _rt::as_i32(port2), - _rt::as_i32(flow_info2), - _rt::as_i32(t3_0), - _rt::as_i32(t3_1), - _rt::as_i32(t3_2), - _rt::as_i32(t3_3), - _rt::as_i32(t3_4), - _rt::as_i32(t3_5), - _rt::as_i32(t3_6), - _rt::as_i32(t3_7), - _rt::as_i32(scope_id2), - ) - } - }; - - ( - 1i32, result5_0, result5_1, result5_2, result5_3, result5_4, - result5_5, result5_6, result5_7, result5_8, result5_9, - result5_10, result5_11, - ) - } - None => ( - 0i32, 0i32, 0i32, 0i32, 0i32, 0i32, 0i32, 0i32, 0i32, 0i32, 0i32, - 0i32, 0i32, - ), - }; - let ptr7 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.stream"] - fn wit_import( - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: *mut u8, - ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import( - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: *mut u8, - ) { - unreachable!() - } - wit_import( - (self).handle() as i32, - result6_0, - result6_1, - result6_2, - result6_3, - result6_4, - result6_5, - result6_6, - result6_7, - result6_8, - result6_9, - result6_10, - result6_11, - result6_12, - ptr7, - ); - let l8 = i32::from(*ptr7.add(0).cast::()); - match l8 { - 0 => { - let e = { - let l9 = *ptr7.add(4).cast::(); - let l10 = *ptr7.add(8).cast::(); - - ( - IncomingDatagramStream::from_handle(l9 as u32), - OutgoingDatagramStream::from_handle(l10 as u32), - ) - }; - Ok(e) - } - 1 => { - let e = { - let l11 = i32::from(*ptr7.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l11 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Get the current bound address. - /// - /// POSIX mentions: - /// > If the socket has not been bound to a local name, the value - /// > stored in the object pointed to by `address` is unspecified. - /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - pub fn local_address(&self) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 36]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 36]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.local-address"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(4).cast::()); - use super::super::super::wasi::sockets::network::IpSocketAddress as V19; - let v19 = match l2 { - 0 => { - let e19 = { - let l3 = i32::from(*ptr0.add(8).cast::()); - let l4 = i32::from(*ptr0.add(10).cast::()); - let l5 = i32::from(*ptr0.add(11).cast::()); - let l6 = i32::from(*ptr0.add(12).cast::()); - let l7 = i32::from(*ptr0.add(13).cast::()); - - super::super::super::wasi::sockets::network::Ipv4SocketAddress{ - port: l3 as u16, - address: (l4 as u8, l5 as u8, l6 as u8, l7 as u8), - } - }; - V19::Ipv4(e19) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - let e19 = { - let l8 = i32::from(*ptr0.add(8).cast::()); - let l9 = *ptr0.add(12).cast::(); - let l10 = i32::from(*ptr0.add(16).cast::()); - let l11 = i32::from(*ptr0.add(18).cast::()); - let l12 = i32::from(*ptr0.add(20).cast::()); - let l13 = i32::from(*ptr0.add(22).cast::()); - let l14 = i32::from(*ptr0.add(24).cast::()); - let l15 = i32::from(*ptr0.add(26).cast::()); - let l16 = i32::from(*ptr0.add(28).cast::()); - let l17 = i32::from(*ptr0.add(30).cast::()); - let l18 = *ptr0.add(32).cast::(); - - super::super::super::wasi::sockets::network::Ipv6SocketAddress{ - port: l8 as u16, - flow_info: l9 as u32, - address: (l10 as u16, l11 as u16, l12 as u16, l13 as u16, l14 as u16, l15 as u16, l16 as u16, l17 as u16), - scope_id: l18 as u32, - } - }; - V19::Ipv6(e19) - } - }; - - v19 - }; - Ok(e) - } - 1 => { - let e = { - let l20 = i32::from(*ptr0.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l20 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Get the address the socket is currently streaming to. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - pub fn remote_address(&self) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 36]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 36]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.remote-address"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(4).cast::()); - use super::super::super::wasi::sockets::network::IpSocketAddress as V19; - let v19 = match l2 { - 0 => { - let e19 = { - let l3 = i32::from(*ptr0.add(8).cast::()); - let l4 = i32::from(*ptr0.add(10).cast::()); - let l5 = i32::from(*ptr0.add(11).cast::()); - let l6 = i32::from(*ptr0.add(12).cast::()); - let l7 = i32::from(*ptr0.add(13).cast::()); - - super::super::super::wasi::sockets::network::Ipv4SocketAddress{ - port: l3 as u16, - address: (l4 as u8, l5 as u8, l6 as u8, l7 as u8), - } - }; - V19::Ipv4(e19) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - let e19 = { - let l8 = i32::from(*ptr0.add(8).cast::()); - let l9 = *ptr0.add(12).cast::(); - let l10 = i32::from(*ptr0.add(16).cast::()); - let l11 = i32::from(*ptr0.add(18).cast::()); - let l12 = i32::from(*ptr0.add(20).cast::()); - let l13 = i32::from(*ptr0.add(22).cast::()); - let l14 = i32::from(*ptr0.add(24).cast::()); - let l15 = i32::from(*ptr0.add(26).cast::()); - let l16 = i32::from(*ptr0.add(28).cast::()); - let l17 = i32::from(*ptr0.add(30).cast::()); - let l18 = *ptr0.add(32).cast::(); - - super::super::super::wasi::sockets::network::Ipv6SocketAddress{ - port: l8 as u16, - flow_info: l9 as u32, - address: (l10 as u16, l11 as u16, l12 as u16, l13 as u16, l14 as u16, l15 as u16, l16 as u16, l17 as u16), - scope_id: l18 as u32, - } - }; - V19::Ipv6(e19) - } - }; - - v19 - }; - Ok(e) - } - 1 => { - let e = { - let l20 = i32::from(*ptr0.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l20 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - pub fn address_family(&self) -> IpAddressFamily { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.address-family"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - super::super::super::wasi::sockets::network::IpAddressFamily::_lift( - ret as u8, - ) - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - pub fn unicast_hop_limit(&self) -> Result { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.unicast-hop-limit"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - l2 as u8 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn set_unicast_hop_limit(&self, value: u8) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.set-unicast-hop-limit"] - fn wit_import(_: i32, _: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i32(&value), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - pub fn receive_buffer_size(&self) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.receive-buffer-size"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn set_receive_buffer_size(&self, value: u64) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.set-receive-buffer-size"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&value), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn send_buffer_size(&self) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.send-buffer-size"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn set_send_buffer_size(&self, value: u64) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.set-send-buffer-size"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&value), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl UdpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - pub fn subscribe(&self) -> Pollable { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]udp-socket.subscribe"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - super::super::super::wasi::io::poll::Pollable::from_handle(ret as u32) - } - } - } - impl IncomingDatagramStream { - #[allow(unused_unsafe, clippy::all)] - /// Receive messages on the socket. - /// - /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. - /// The returned list may contain fewer elements than requested, but never more. - /// - /// This function returns successfully with an empty list when either: - /// - `max-results` is 0, or: - /// - `max-results` is greater than 0, but no results are immediately available. - /// This function never returns `error(would-block)`. - /// - /// # Typical errors - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - pub fn receive( - &self, - max_results: u64, - ) -> Result<_rt::Vec, ErrorCode> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]incoming-datagram-stream.receive"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&max_results), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::<*mut u8>(); - let l3 = *ptr0.add(8).cast::(); - let base25 = l2; - let len25 = l3; - let mut result25 = _rt::Vec::with_capacity(len25); - for i in 0..len25 { - let base = base25.add(i * 40); - let e25 = { - let l4 = *base.add(0).cast::<*mut u8>(); - let l5 = *base.add(4).cast::(); - let len6 = l5; - let l7 = i32::from(*base.add(8).cast::()); - use super::super::super::wasi::sockets::network::IpSocketAddress as V24; - let v24 = match l7 { - 0 => { - let e24 = { - let l8 = - i32::from(*base.add(12).cast::()); - let l9 = - i32::from(*base.add(14).cast::()); - let l10 = - i32::from(*base.add(15).cast::()); - let l11 = - i32::from(*base.add(16).cast::()); - let l12 = - i32::from(*base.add(17).cast::()); - - super::super::super::wasi::sockets::network::Ipv4SocketAddress{ - port: l8 as u16, - address: (l9 as u8, l10 as u8, l11 as u8, l12 as u8), - } - }; - V24::Ipv4(e24) - } - n => { - debug_assert_eq!( - n, 1, - "invalid enum discriminant" - ); - let e24 = { - let l13 = - i32::from(*base.add(12).cast::()); - let l14 = *base.add(16).cast::(); - let l15 = - i32::from(*base.add(20).cast::()); - let l16 = - i32::from(*base.add(22).cast::()); - let l17 = - i32::from(*base.add(24).cast::()); - let l18 = - i32::from(*base.add(26).cast::()); - let l19 = - i32::from(*base.add(28).cast::()); - let l20 = - i32::from(*base.add(30).cast::()); - let l21 = - i32::from(*base.add(32).cast::()); - let l22 = - i32::from(*base.add(34).cast::()); - let l23 = *base.add(36).cast::(); - - super::super::super::wasi::sockets::network::Ipv6SocketAddress{ - port: l13 as u16, - flow_info: l14 as u32, - address: (l15 as u16, l16 as u16, l17 as u16, l18 as u16, l19 as u16, l20 as u16, l21 as u16, l22 as u16), - scope_id: l23 as u32, - } - }; - V24::Ipv6(e24) - } - }; - - IncomingDatagram { - data: _rt::Vec::from_raw_parts( - l4.cast(), - len6, - len6, - ), - remote_address: v24, - } - }; - result25.push(e25); - } - _rt::cabi_dealloc(base25, len25 * 40, 4); - - result25 - }; - Ok(e) - } - 1 => { - let e = { - let l26 = i32::from(*ptr0.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l26 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl IncomingDatagramStream { - #[allow(unused_unsafe, clippy::all)] - /// Create a `pollable` which will resolve once the stream is ready to receive again. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - pub fn subscribe(&self) -> Pollable { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]incoming-datagram-stream.subscribe"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - super::super::super::wasi::io::poll::Pollable::from_handle(ret as u32) - } - } - } - impl OutgoingDatagramStream { - #[allow(unused_unsafe, clippy::all)] - /// Check readiness for sending. This function never blocks. - /// - /// Returns the number of datagrams permitted for the next call to `send`, - /// or an error. Calling `send` with more datagrams than this function has - /// permitted will trap. - /// - /// When this function returns ok(0), the `subscribe` pollable will - /// become ready when this function will report at least ok(1), or an - /// error. - /// - /// Never returns `would-block`. - pub fn check_send(&self) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]outgoing-datagram-stream.check-send"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl OutgoingDatagramStream { - #[allow(unused_unsafe, clippy::all)] - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). This function never - /// returns `error(would-block)`. If none of the datagrams were able to be sent, `ok(0)` is returned. - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// Each call to `send` must be permitted by a preceding `check-send`. Implementations must trap if - /// either `check-send` was not called or `datagrams` contains more items than `check-send` permitted. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) - /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - pub fn send(&self, datagrams: &[OutgoingDatagram]) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let vec7 = datagrams; - let len7 = vec7.len(); - let layout7 = - _rt::alloc::Layout::from_size_align_unchecked(vec7.len() * 44, 4); - let result7 = if layout7.size() != 0 { - let ptr = _rt::alloc::alloc(layout7).cast::(); - if ptr.is_null() { - _rt::alloc::handle_alloc_error(layout7); - } - ptr - } else { - { - ::core::ptr::null_mut() - } - }; - for (i, e) in vec7.into_iter().enumerate() { - let base = result7.add(i * 44); - { - let OutgoingDatagram { - data: data0, - remote_address: remote_address0, - } = e; - let vec1 = data0; - let ptr1 = vec1.as_ptr().cast::(); - let len1 = vec1.len(); - *base.add(4).cast::() = len1; - *base.add(0).cast::<*mut u8>() = ptr1.cast_mut(); - match remote_address0 { - Some(e) => { - *base.add(8).cast::() = (1i32) as u8; - use super::super::super::wasi::sockets::network::IpSocketAddress as V6; - match e { - V6::Ipv4(e) => { - *base.add(12).cast::() = (0i32) as u8; - let super::super::super::wasi::sockets::network::Ipv4SocketAddress{ port:port2, address:address2, } = e; - *base.add(16).cast::() = - (_rt::as_i32(port2)) as u16; - let (t3_0, t3_1, t3_2, t3_3) = address2; - *base.add(18).cast::() = - (_rt::as_i32(t3_0)) as u8; - *base.add(19).cast::() = - (_rt::as_i32(t3_1)) as u8; - *base.add(20).cast::() = - (_rt::as_i32(t3_2)) as u8; - *base.add(21).cast::() = - (_rt::as_i32(t3_3)) as u8; - } - V6::Ipv6(e) => { - *base.add(12).cast::() = (1i32) as u8; - let super::super::super::wasi::sockets::network::Ipv6SocketAddress{ port:port4, flow_info:flow_info4, address:address4, scope_id:scope_id4, } = e; - *base.add(16).cast::() = - (_rt::as_i32(port4)) as u16; - *base.add(20).cast::() = - _rt::as_i32(flow_info4); - let ( - t5_0, - t5_1, - t5_2, - t5_3, - t5_4, - t5_5, - t5_6, - t5_7, - ) = address4; - *base.add(24).cast::() = - (_rt::as_i32(t5_0)) as u16; - *base.add(26).cast::() = - (_rt::as_i32(t5_1)) as u16; - *base.add(28).cast::() = - (_rt::as_i32(t5_2)) as u16; - *base.add(30).cast::() = - (_rt::as_i32(t5_3)) as u16; - *base.add(32).cast::() = - (_rt::as_i32(t5_4)) as u16; - *base.add(34).cast::() = - (_rt::as_i32(t5_5)) as u16; - *base.add(36).cast::() = - (_rt::as_i32(t5_6)) as u16; - *base.add(38).cast::() = - (_rt::as_i32(t5_7)) as u16; - *base.add(40).cast::() = - _rt::as_i32(scope_id4); - } - } - } - None => { - *base.add(8).cast::() = (0i32) as u8; - } - }; - } - } - let ptr8 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]outgoing-datagram-stream.send"] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, result7, len7, ptr8); - let l9 = i32::from(*ptr8.add(0).cast::()); - if layout7.size() != 0 { - _rt::alloc::dealloc(result7.cast(), layout7); - } - match l9 { - 0 => { - let e = { - let l10 = *ptr8.add(8).cast::(); - - l10 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l11 = i32::from(*ptr8.add(8).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l11 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl OutgoingDatagramStream { - #[allow(unused_unsafe, clippy::all)] - /// Create a `pollable` which will resolve once the stream is ready to send again. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - pub fn subscribe(&self) -> Pollable { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp@0.2.0")] - extern "C" { - #[link_name = "[method]outgoing-datagram-stream.subscribe"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - super::super::super::wasi::io::poll::Pollable::from_handle(ret as u32) - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod udp_create_socket { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type ErrorCode = super::super::super::wasi::sockets::network::ErrorCode; - pub type IpAddressFamily = super::super::super::wasi::sockets::network::IpAddressFamily; - pub type UdpSocket = super::super::super::wasi::sockets::udp::UdpSocket; - #[allow(unused_unsafe, clippy::all)] - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. - /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, - /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References: - /// - - /// - - /// - - /// - - pub fn create_udp_socket( - address_family: IpAddressFamily, - ) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/udp-create-socket@0.2.0")] - extern "C" { - #[link_name = "create-udp-socket"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import(address_family.clone() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - - super::super::super::wasi::sockets::udp::UdpSocket::from_handle( - l2 as u32, - ) - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod tcp { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type InputStream = super::super::super::wasi::io::streams::InputStream; - pub type OutputStream = super::super::super::wasi::io::streams::OutputStream; - pub type Pollable = super::super::super::wasi::io::poll::Pollable; - pub type Duration = super::super::super::wasi::clocks::monotonic_clock::Duration; - pub type Network = super::super::super::wasi::sockets::network::Network; - pub type ErrorCode = super::super::super::wasi::sockets::network::ErrorCode; - pub type IpSocketAddress = super::super::super::wasi::sockets::network::IpSocketAddress; - pub type IpAddressFamily = super::super::super::wasi::sockets::network::IpAddressFamily; - #[repr(u8)] - #[derive(Clone, Copy, Eq, PartialEq)] - pub enum ShutdownType { - /// Similar to `SHUT_RD` in POSIX. - Receive, - /// Similar to `SHUT_WR` in POSIX. - Send, - /// Similar to `SHUT_RDWR` in POSIX. - Both, - } - impl ::core::fmt::Debug for ShutdownType { - fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result { - match self { - ShutdownType::Receive => f.debug_tuple("ShutdownType::Receive").finish(), - ShutdownType::Send => f.debug_tuple("ShutdownType::Send").finish(), - ShutdownType::Both => f.debug_tuple("ShutdownType::Both").finish(), - } - } - } - - impl ShutdownType { - pub(crate) unsafe fn _lift(val: u8) -> ShutdownType { - if !cfg!(debug_assertions) { - return ::core::mem::transmute(val); - } - - match val { - 0 => ShutdownType::Receive, - 1 => ShutdownType::Send, - 2 => ShutdownType::Both, - - _ => panic!("invalid enum discriminant"), - } - } - } - - /// A TCP socket resource. - /// - /// The socket can be in one of the following states: - /// - `unbound` - /// - `bind-in-progress` - /// - `bound` (See note below) - /// - `listen-in-progress` - /// - `listening` - /// - `connect-in-progress` - /// - `connected` - /// - `closed` - /// See - /// for a more information. - /// - /// Note: Except where explicitly mentioned, whenever this documentation uses - /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. - /// (i.e. `bound`, `listen-in-progress`, `listening`, `connect-in-progress` or `connected`) - /// - /// In addition to the general error codes documented on the - /// `network::error-code` type, TCP socket methods may always return - /// `error(invalid-state)` when in the `closed` state. - - #[derive(Debug)] - #[repr(transparent)] - pub struct TcpSocket { - handle: _rt::Resource, - } - - impl TcpSocket { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for TcpSocket { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]tcp-socket"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// Bind can be attempted multiple times on the same socket, even with - /// different arguments on each iteration. But never concurrently and - /// only as long as the previous bind failed. Once a bind succeeds, the - /// binding can't be changed anymore. - /// - /// # Typical errors - /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) - /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) - /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) - /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT - /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR - /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior - /// and SO_REUSEADDR performs something different entirely. - /// - /// Unlike in POSIX, in WASI the bind operation is async. This enables - /// interactive WASI hosts to inject permission prompts. Runtimes that - /// don't want to make use of this ability can simply call the native - /// `bind` as part of either `start-bind` or `finish-bind`. - /// - /// # References - /// - - /// - - /// - - /// - - pub fn start_bind( - &self, - network: &Network, - local_address: IpSocketAddress, - ) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - use super::super::super::wasi::sockets::network::IpSocketAddress as V4; - let ( - result5_0, - result5_1, - result5_2, - result5_3, - result5_4, - result5_5, - result5_6, - result5_7, - result5_8, - result5_9, - result5_10, - result5_11, - ) = match local_address { - V4::Ipv4(e) => { - let super::super::super::wasi::sockets::network::Ipv4SocketAddress{ port:port0, address:address0, } = e; - let (t1_0, t1_1, t1_2, t1_3) = address0; - - ( - 0i32, - _rt::as_i32(port0), - _rt::as_i32(t1_0), - _rt::as_i32(t1_1), - _rt::as_i32(t1_2), - _rt::as_i32(t1_3), - 0i32, - 0i32, - 0i32, - 0i32, - 0i32, - 0i32, - ) - } - V4::Ipv6(e) => { - let super::super::super::wasi::sockets::network::Ipv6SocketAddress{ port:port2, flow_info:flow_info2, address:address2, scope_id:scope_id2, } = e; - let (t3_0, t3_1, t3_2, t3_3, t3_4, t3_5, t3_6, t3_7) = address2; - - ( - 1i32, - _rt::as_i32(port2), - _rt::as_i32(flow_info2), - _rt::as_i32(t3_0), - _rt::as_i32(t3_1), - _rt::as_i32(t3_2), - _rt::as_i32(t3_3), - _rt::as_i32(t3_4), - _rt::as_i32(t3_5), - _rt::as_i32(t3_6), - _rt::as_i32(t3_7), - _rt::as_i32(scope_id2), - ) - } - }; - let ptr6 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.start-bind"] - fn wit_import( - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: *mut u8, - ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import( - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: *mut u8, - ) { - unreachable!() - } - wit_import( - (self).handle() as i32, - (network).handle() as i32, - result5_0, - result5_1, - result5_2, - result5_3, - result5_4, - result5_5, - result5_6, - result5_7, - result5_8, - result5_9, - result5_10, - result5_11, - ptr6, - ); - let l7 = i32::from(*ptr6.add(0).cast::()); - match l7 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l8 = i32::from(*ptr6.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l8 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn finish_bind(&self) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.finish-bind"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Connect to a remote endpoint. - /// - /// On success: - /// - the socket is transitioned into the `connection` state. - /// - a pair of streams is returned that can be used to read & write to the connection - /// - /// After a failed connection attempt, the socket will be in the `closed` - /// state and the only valid action left is to `drop` the socket. A single - /// socket can not be used to connect more than once. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) - /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) - /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A connect operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// The POSIX equivalent of `start-connect` is the regular `connect` syscall. - /// Because all WASI sockets are non-blocking this is expected to return - /// EINPROGRESS, which should be translated to `ok()` in WASI. - /// - /// The POSIX equivalent of `finish-connect` is a `poll` for event `POLLOUT` - /// with a timeout of 0 on the socket descriptor. Followed by a check for - /// the `SO_ERROR` socket option, in case the poll signaled readiness. - /// - /// # References - /// - - /// - - /// - - /// - - pub fn start_connect( - &self, - network: &Network, - remote_address: IpSocketAddress, - ) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - use super::super::super::wasi::sockets::network::IpSocketAddress as V4; - let ( - result5_0, - result5_1, - result5_2, - result5_3, - result5_4, - result5_5, - result5_6, - result5_7, - result5_8, - result5_9, - result5_10, - result5_11, - ) = match remote_address { - V4::Ipv4(e) => { - let super::super::super::wasi::sockets::network::Ipv4SocketAddress{ port:port0, address:address0, } = e; - let (t1_0, t1_1, t1_2, t1_3) = address0; - - ( - 0i32, - _rt::as_i32(port0), - _rt::as_i32(t1_0), - _rt::as_i32(t1_1), - _rt::as_i32(t1_2), - _rt::as_i32(t1_3), - 0i32, - 0i32, - 0i32, - 0i32, - 0i32, - 0i32, - ) - } - V4::Ipv6(e) => { - let super::super::super::wasi::sockets::network::Ipv6SocketAddress{ port:port2, flow_info:flow_info2, address:address2, scope_id:scope_id2, } = e; - let (t3_0, t3_1, t3_2, t3_3, t3_4, t3_5, t3_6, t3_7) = address2; - - ( - 1i32, - _rt::as_i32(port2), - _rt::as_i32(flow_info2), - _rt::as_i32(t3_0), - _rt::as_i32(t3_1), - _rt::as_i32(t3_2), - _rt::as_i32(t3_3), - _rt::as_i32(t3_4), - _rt::as_i32(t3_5), - _rt::as_i32(t3_6), - _rt::as_i32(t3_7), - _rt::as_i32(scope_id2), - ) - } - }; - let ptr6 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.start-connect"] - fn wit_import( - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: *mut u8, - ); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import( - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: i32, - _: *mut u8, - ) { - unreachable!() - } - wit_import( - (self).handle() as i32, - (network).handle() as i32, - result5_0, - result5_1, - result5_2, - result5_3, - result5_4, - result5_5, - result5_6, - result5_7, - result5_8, - result5_9, - result5_10, - result5_11, - ptr6, - ); - let l7 = i32::from(*ptr6.add(0).cast::()); - match l7 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l8 = i32::from(*ptr6.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l8 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn finish_connect(&self) -> Result<(InputStream, OutputStream), ErrorCode> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 12]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 12]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.finish-connect"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - let l3 = *ptr0.add(8).cast::(); - - (super::super::super::wasi::io::streams::InputStream::from_handle(l2 as u32), super::super::super::wasi::io::streams::OutputStream::from_handle(l3 as u32)) - }; - Ok(e) - } - 1 => { - let e = { - let l4 = i32::from(*ptr0.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l4 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Start listening for new connections. - /// - /// Transitions the socket into the `listening` state. - /// - /// Unlike POSIX, the socket must already be explicitly bound. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) - /// - `invalid-state`: The socket is already in the `listening` state. - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A listen operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// Unlike in POSIX, in WASI the listen operation is async. This enables - /// interactive WASI hosts to inject permission prompts. Runtimes that - /// don't want to make use of this ability can simply call the native - /// `listen` as part of either `start-listen` or `finish-listen`. - /// - /// # References - /// - - /// - - /// - - /// - - pub fn start_listen(&self) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.start-listen"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn finish_listen(&self) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.finish-listen"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Accept a new client socket. - /// - /// The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket: - /// - `address-family` - /// - `keep-alive-enabled` - /// - `keep-alive-idle-time` - /// - `keep-alive-interval` - /// - `keep-alive-count` - /// - `hop-limit` - /// - `receive-buffer-size` - /// - `send-buffer-size` - /// - /// On success, this function returns the newly accepted client socket along with - /// a pair of streams that can be used to read & write to the connection. - /// - /// # Typical errors - /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) - /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) - /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References - /// - - /// - - /// - - /// - - pub fn accept(&self) -> Result<(TcpSocket, InputStream, OutputStream), ErrorCode> { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.accept"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - let l3 = *ptr0.add(8).cast::(); - let l4 = *ptr0.add(12).cast::(); - - (TcpSocket::from_handle(l2 as u32), super::super::super::wasi::io::streams::InputStream::from_handle(l3 as u32), super::super::super::wasi::io::streams::OutputStream::from_handle(l4 as u32)) - }; - Ok(e) - } - 1 => { - let e = { - let l5 = i32::from(*ptr0.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l5 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Get the bound local address. - /// - /// POSIX mentions: - /// > If the socket has not been bound to a local name, the value - /// > stored in the object pointed to by `address` is unspecified. - /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - pub fn local_address(&self) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 36]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 36]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.local-address"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(4).cast::()); - use super::super::super::wasi::sockets::network::IpSocketAddress as V19; - let v19 = match l2 { - 0 => { - let e19 = { - let l3 = i32::from(*ptr0.add(8).cast::()); - let l4 = i32::from(*ptr0.add(10).cast::()); - let l5 = i32::from(*ptr0.add(11).cast::()); - let l6 = i32::from(*ptr0.add(12).cast::()); - let l7 = i32::from(*ptr0.add(13).cast::()); - - super::super::super::wasi::sockets::network::Ipv4SocketAddress{ - port: l3 as u16, - address: (l4 as u8, l5 as u8, l6 as u8, l7 as u8), - } - }; - V19::Ipv4(e19) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - let e19 = { - let l8 = i32::from(*ptr0.add(8).cast::()); - let l9 = *ptr0.add(12).cast::(); - let l10 = i32::from(*ptr0.add(16).cast::()); - let l11 = i32::from(*ptr0.add(18).cast::()); - let l12 = i32::from(*ptr0.add(20).cast::()); - let l13 = i32::from(*ptr0.add(22).cast::()); - let l14 = i32::from(*ptr0.add(24).cast::()); - let l15 = i32::from(*ptr0.add(26).cast::()); - let l16 = i32::from(*ptr0.add(28).cast::()); - let l17 = i32::from(*ptr0.add(30).cast::()); - let l18 = *ptr0.add(32).cast::(); - - super::super::super::wasi::sockets::network::Ipv6SocketAddress{ - port: l8 as u16, - flow_info: l9 as u32, - address: (l10 as u16, l11 as u16, l12 as u16, l13 as u16, l14 as u16, l15 as u16, l16 as u16, l17 as u16), - scope_id: l18 as u32, - } - }; - V19::Ipv6(e19) - } - }; - - v19 - }; - Ok(e) - } - 1 => { - let e = { - let l20 = i32::from(*ptr0.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l20 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Get the remote address. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - pub fn remote_address(&self) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 36]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 36]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.remote-address"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(4).cast::()); - use super::super::super::wasi::sockets::network::IpSocketAddress as V19; - let v19 = match l2 { - 0 => { - let e19 = { - let l3 = i32::from(*ptr0.add(8).cast::()); - let l4 = i32::from(*ptr0.add(10).cast::()); - let l5 = i32::from(*ptr0.add(11).cast::()); - let l6 = i32::from(*ptr0.add(12).cast::()); - let l7 = i32::from(*ptr0.add(13).cast::()); - - super::super::super::wasi::sockets::network::Ipv4SocketAddress{ - port: l3 as u16, - address: (l4 as u8, l5 as u8, l6 as u8, l7 as u8), - } - }; - V19::Ipv4(e19) - } - n => { - debug_assert_eq!(n, 1, "invalid enum discriminant"); - let e19 = { - let l8 = i32::from(*ptr0.add(8).cast::()); - let l9 = *ptr0.add(12).cast::(); - let l10 = i32::from(*ptr0.add(16).cast::()); - let l11 = i32::from(*ptr0.add(18).cast::()); - let l12 = i32::from(*ptr0.add(20).cast::()); - let l13 = i32::from(*ptr0.add(22).cast::()); - let l14 = i32::from(*ptr0.add(24).cast::()); - let l15 = i32::from(*ptr0.add(26).cast::()); - let l16 = i32::from(*ptr0.add(28).cast::()); - let l17 = i32::from(*ptr0.add(30).cast::()); - let l18 = *ptr0.add(32).cast::(); - - super::super::super::wasi::sockets::network::Ipv6SocketAddress{ - port: l8 as u16, - flow_info: l9 as u32, - address: (l10 as u16, l11 as u16, l12 as u16, l13 as u16, l14 as u16, l15 as u16, l16 as u16, l17 as u16), - scope_id: l18 as u32, - } - }; - V19::Ipv6(e19) - } - }; - - v19 - }; - Ok(e) - } - 1 => { - let e = { - let l20 = i32::from(*ptr0.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l20 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Whether the socket is in the `listening` state. - /// - /// Equivalent to the SO_ACCEPTCONN socket option. - pub fn is_listening(&self) -> bool { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.is-listening"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - _rt::bool_lift(ret as u8) - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - pub fn address_family(&self) -> IpAddressFamily { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.address-family"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - super::super::super::wasi::sockets::network::IpAddressFamily::_lift( - ret as u8, - ) - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Hints the desired listen queue size. Implementations are free to ignore this. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// - /// # Typical errors - /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. - /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. - pub fn set_listen_backlog_size(&self, value: u64) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.set-listen-backlog-size"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&value), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Enables or disables keepalive. - /// - /// The keepalive behavior can be adjusted using: - /// - `keep-alive-idle-time` - /// - `keep-alive-interval` - /// - `keep-alive-count` - /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. - /// - /// Equivalent to the SO_KEEPALIVE socket option. - pub fn keep_alive_enabled(&self) -> Result { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.keep-alive-enabled"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - _rt::bool_lift(l2 as u8) - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn set_keep_alive_enabled(&self, value: bool) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.set-keep-alive-enabled"] - fn wit_import(_: i32, _: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i32, _: *mut u8) { - unreachable!() - } - wit_import( - (self).handle() as i32, - match &value { - true => 1, - false => 0, - }, - ptr0, - ); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - pub fn keep_alive_idle_time(&self) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.keep-alive-idle-time"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn set_keep_alive_idle_time(&self, value: Duration) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.set-keep-alive-idle-time"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(value), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// The time between keepalive packets. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPINTVL socket option. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - pub fn keep_alive_interval(&self) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.keep-alive-interval"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn set_keep_alive_interval(&self, value: Duration) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.set-keep-alive-interval"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(value), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// The maximum amount of keepalive packets TCP should send before aborting the connection. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPCNT socket option. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - pub fn keep_alive_count(&self) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.keep-alive-count"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - - l2 as u32 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn set_keep_alive_count(&self, value: u32) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.set-keep-alive-count"] - fn wit_import(_: i32, _: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i32(&value), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - pub fn hop_limit(&self) -> Result { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.hop-limit"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - l2 as u8 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn set_hop_limit(&self, value: u8) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.set-hop-limit"] - fn wit_import(_: i32, _: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i32(&value), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - pub fn receive_buffer_size(&self) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.receive-buffer-size"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn set_receive_buffer_size(&self, value: u64) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.set-receive-buffer-size"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&value), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn send_buffer_size(&self) -> Result { - unsafe { - #[repr(align(8))] - struct RetArea([::core::mem::MaybeUninit; 16]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 16]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.send-buffer-size"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(8).cast::(); - - l2 as u64 - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(8).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - pub fn set_send_buffer_size(&self, value: u64) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.set-send-buffer-size"] - fn wit_import(_: i32, _: i64, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i64, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, _rt::as_i64(&value), ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Create a `pollable` which can be used to poll for, or block on, - /// completion of any of the asynchronous operations of this socket. - /// - /// When `finish-bind`, `finish-listen`, `finish-connect` or `accept` - /// return `error(would-block)`, this pollable can be used to wait for - /// their success or failure, after which the method can be retried. - /// - /// The pollable is not limited to the async operation that happens to be - /// in progress at the time of calling `subscribe` (if any). Theoretically, - /// `subscribe` only has to be called once per socket and can then be - /// (re)used for the remainder of the socket's lifetime. - /// - /// See - /// for a more information. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - pub fn subscribe(&self) -> Pollable { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.subscribe"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - super::super::super::wasi::io::poll::Pollable::from_handle(ret as u32) - } - } - } - impl TcpSocket { - #[allow(unused_unsafe, clippy::all)] - /// Initiate a graceful shutdown. - /// - /// - `receive`: The socket is not expecting to receive any data from - /// the peer. The `input-stream` associated with this socket will be - /// closed. Any data still in the receive queue at time of calling - /// this method will be discarded. - /// - `send`: The socket has no more data to send to the peer. The `output-stream` - /// associated with this socket will be closed and a FIN packet will be sent. - /// - `both`: Same effect as `receive` & `send` combined. - /// - /// This function is idempotent. Shutting a down a direction more than once - /// has no effect and returns `ok`. - /// - /// The shutdown function does not close (drop) the socket. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - pub fn shutdown(&self, shutdown_type: ShutdownType) -> Result<(), ErrorCode> { - unsafe { - #[repr(align(1))] - struct RetArea([::core::mem::MaybeUninit; 2]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 2]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp@0.2.0")] - extern "C" { - #[link_name = "[method]tcp-socket.shutdown"] - fn wit_import(_: i32, _: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, shutdown_type.clone() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = (); - Ok(e) - } - 1 => { - let e = { - let l2 = i32::from(*ptr0.add(1).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l2 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod tcp_create_socket { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type ErrorCode = super::super::super::wasi::sockets::network::ErrorCode; - pub type IpAddressFamily = super::super::super::wasi::sockets::network::IpAddressFamily; - pub type TcpSocket = super::super::super::wasi::sockets::tcp::TcpSocket; - #[allow(unused_unsafe, clippy::all)] - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. - /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` - /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References - /// - - /// - - /// - - /// - - pub fn create_tcp_socket( - address_family: IpAddressFamily, - ) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/tcp-create-socket@0.2.0")] - extern "C" { - #[link_name = "create-tcp-socket"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import(address_family.clone() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = *ptr0.add(4).cast::(); - - super::super::super::wasi::sockets::tcp::TcpSocket::from_handle( - l2 as u32, - ) - }; - Ok(e) - } - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l3 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - - #[allow(dead_code, clippy::all)] - pub mod ip_name_lookup { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::__link_custom_section_describing_imports; - use super::super::super::_rt; - pub type Pollable = super::super::super::wasi::io::poll::Pollable; - pub type Network = super::super::super::wasi::sockets::network::Network; - pub type ErrorCode = super::super::super::wasi::sockets::network::ErrorCode; - pub type IpAddress = super::super::super::wasi::sockets::network::IpAddress; - - #[derive(Debug)] - #[repr(transparent)] - pub struct ResolveAddressStream { - handle: _rt::Resource, - } - - impl ResolveAddressStream { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - Self { - handle: _rt::Resource::from_handle(handle), - } - } - - #[doc(hidden)] - pub fn take_handle(&self) -> u32 { - _rt::Resource::take_handle(&self.handle) - } - - #[doc(hidden)] - pub fn handle(&self) -> u32 { - _rt::Resource::handle(&self.handle) - } - } - - unsafe impl _rt::WasmResource for ResolveAddressStream { - #[inline] - unsafe fn drop(_handle: u32) { - #[cfg(not(target_arch = "wasm32"))] - unreachable!(); - - #[cfg(target_arch = "wasm32")] - { - #[link(wasm_import_module = "wasi:sockets/ip-name-lookup@0.2.0")] - extern "C" { - #[link_name = "[resource-drop]resolve-address-stream"] - fn drop(_: u32); - } - - drop(_handle); - } - } - } - - #[allow(unused_unsafe, clippy::all)] - /// Resolve an internet host name to a list of IP addresses. - /// - /// Unicode domain names are automatically converted to ASCII using IDNA encoding. - /// If the input is an IP address string, the address is parsed and returned - /// as-is without making any external requests. - /// - /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. - /// - /// This function never blocks. It either immediately fails or immediately - /// returns successfully with a `resolve-address-stream` that can be used - /// to (asynchronously) fetch the results. - /// - /// # Typical errors - /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. - /// - /// # References: - /// - - /// - - /// - - /// - - pub fn resolve_addresses( - network: &Network, - name: &str, - ) -> Result { - unsafe { - #[repr(align(4))] - struct RetArea([::core::mem::MaybeUninit; 8]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 8]); - let vec0 = name; - let ptr0 = vec0.as_ptr().cast::(); - let len0 = vec0.len(); - let ptr1 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/ip-name-lookup@0.2.0")] - extern "C" { - #[link_name = "resolve-addresses"] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8, _: usize, _: *mut u8) { - unreachable!() - } - wit_import((network).handle() as i32, ptr0.cast_mut(), len0, ptr1); - let l2 = i32::from(*ptr1.add(0).cast::()); - match l2 { - 0 => { - let e = { - let l3 = *ptr1.add(4).cast::(); - - ResolveAddressStream::from_handle(l3 as u32) - }; - Ok(e) - } - 1 => { - let e = { - let l4 = i32::from(*ptr1.add(4).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l4 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - impl ResolveAddressStream { - #[allow(unused_unsafe, clippy::all)] - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - pub fn resolve_next_address(&self) -> Result, ErrorCode> { - unsafe { - #[repr(align(2))] - struct RetArea([::core::mem::MaybeUninit; 22]); - let mut ret_area = RetArea([::core::mem::MaybeUninit::uninit(); 22]); - let ptr0 = ret_area.0.as_mut_ptr().cast::(); - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/ip-name-lookup@0.2.0")] - extern "C" { - #[link_name = "[method]resolve-address-stream.resolve-next-address"] - fn wit_import(_: i32, _: *mut u8); - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32, _: *mut u8) { - unreachable!() - } - wit_import((self).handle() as i32, ptr0); - let l1 = i32::from(*ptr0.add(0).cast::()); - match l1 { - 0 => { - let e = { - let l2 = i32::from(*ptr0.add(2).cast::()); - - match l2 { - 0 => None, - 1 => { - let e = { - let l3 = i32::from(*ptr0.add(4).cast::()); - use super::super::super::wasi::sockets::network::IpAddress as V16; - let v16 = match l3 { - 0 => { - let e16 = { - let l4 = i32::from( - *ptr0.add(6).cast::(), - ); - let l5 = i32::from( - *ptr0.add(7).cast::(), - ); - let l6 = i32::from( - *ptr0.add(8).cast::(), - ); - let l7 = i32::from( - *ptr0.add(9).cast::(), - ); - - (l4 as u8, l5 as u8, l6 as u8, l7 as u8) - }; - V16::Ipv4(e16) - } - n => { - debug_assert_eq!( - n, 1, - "invalid enum discriminant" - ); - let e16 = { - let l8 = i32::from( - *ptr0.add(6).cast::(), - ); - let l9 = i32::from( - *ptr0.add(8).cast::(), - ); - let l10 = i32::from( - *ptr0.add(10).cast::(), - ); - let l11 = i32::from( - *ptr0.add(12).cast::(), - ); - let l12 = i32::from( - *ptr0.add(14).cast::(), - ); - let l13 = i32::from( - *ptr0.add(16).cast::(), - ); - let l14 = i32::from( - *ptr0.add(18).cast::(), - ); - let l15 = i32::from( - *ptr0.add(20).cast::(), - ); - - ( - l8 as u16, l9 as u16, l10 as u16, - l11 as u16, l12 as u16, l13 as u16, - l14 as u16, l15 as u16, - ) - }; - V16::Ipv6(e16) - } - }; - - v16 - }; - Some(e) - } - _ => _rt::invalid_enum_discriminant(), - } - }; - Ok(e) - } - 1 => { - let e = { - let l17 = i32::from(*ptr0.add(2).cast::()); - - super::super::super::wasi::sockets::network::ErrorCode::_lift( - l17 as u8, - ) - }; - Err(e) - } - _ => _rt::invalid_enum_discriminant(), - } - } - } - } - impl ResolveAddressStream { - #[allow(unused_unsafe, clippy::all)] - /// Create a `pollable` which will resolve once the stream is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - pub fn subscribe(&self) -> Pollable { - unsafe { - #[cfg(target_arch = "wasm32")] - #[link(wasm_import_module = "wasi:sockets/ip-name-lookup@0.2.0")] - extern "C" { - #[link_name = "[method]resolve-address-stream.subscribe"] - fn wit_import(_: i32) -> i32; - } - - #[cfg(not(target_arch = "wasm32"))] - fn wit_import(_: i32) -> i32 { - unreachable!() - } - let ret = wit_import((self).handle() as i32); - super::super::super::wasi::io::poll::Pollable::from_handle(ret as u32) - } - } - } - } - } -} -#[allow(dead_code)] -pub mod exports { - #[allow(dead_code)] - pub mod wasi { - #[allow(dead_code)] - pub mod cli { - #[allow(dead_code, clippy::all)] - pub mod run { - #[used] - #[doc(hidden)] - #[cfg(target_arch = "wasm32")] - static __FORCE_SECTION_REF: fn() = - super::super::super::super::__link_custom_section_describing_imports; - use super::super::super::super::_rt; - #[doc(hidden)] - #[allow(non_snake_case)] - pub unsafe fn _export_run_cabi() -> i32 { - #[cfg(target_arch = "wasm32")] - _rt::run_ctors_once(); - let result0 = T::run(); - let result1 = match result0 { - Ok(_) => 0i32, - Err(_) => 1i32, - }; - result1 - } - pub trait Guest { - /// Run the program. - fn run() -> Result<(), ()>; - } - #[doc(hidden)] - - macro_rules! __export_wasi_cli_run_0_2_0_cabi{ - ($ty:ident with_types_in $($path_to_types:tt)*) => (const _: () = { - - #[export_name = "wasi:cli/run@0.2.0#run"] - unsafe extern "C" fn export_run() -> i32 { - $($path_to_types)*::_export_run_cabi::<$ty>() - } - };); - } - #[doc(hidden)] - pub(crate) use __export_wasi_cli_run_0_2_0_cabi; - } - } - } -} -mod _rt { - pub use alloc_crate::string::String; - pub use alloc_crate::vec::Vec; - pub unsafe fn string_lift(bytes: Vec) -> String { - if cfg!(debug_assertions) { - String::from_utf8(bytes).unwrap() - } else { - String::from_utf8_unchecked(bytes) - } - } - pub unsafe fn cabi_dealloc(ptr: *mut u8, size: usize, align: usize) { - if size == 0 { - return; - } - let layout = alloc::Layout::from_size_align_unchecked(size, align); - alloc::dealloc(ptr as *mut u8, layout); - } - pub unsafe fn invalid_enum_discriminant() -> T { - if cfg!(debug_assertions) { - panic!("invalid enum discriminant") - } else { - core::hint::unreachable_unchecked() - } - } - - use core::fmt; - use core::marker; - use core::sync::atomic::{AtomicU32, Ordering::Relaxed}; - - /// A type which represents a component model resource, either imported or - /// exported into this component. - /// - /// This is a low-level wrapper which handles the lifetime of the resource - /// (namely this has a destructor). The `T` provided defines the component model - /// intrinsics that this wrapper uses. - /// - /// One of the chief purposes of this type is to provide `Deref` implementations - /// to access the underlying data when it is owned. - /// - /// This type is primarily used in generated code for exported and imported - /// resources. - #[repr(transparent)] - pub struct Resource { - // NB: This would ideally be `u32` but it is not. The fact that this has - // interior mutability is not exposed in the API of this type except for the - // `take_handle` method which is supposed to in theory be private. - // - // This represents, almost all the time, a valid handle value. When it's - // invalid it's stored as `u32::MAX`. - handle: AtomicU32, - _marker: marker::PhantomData, - } - - /// A trait which all wasm resources implement, namely providing the ability to - /// drop a resource. - /// - /// This generally is implemented by generated code, not user-facing code. - pub unsafe trait WasmResource { - /// Invokes the `[resource-drop]...` intrinsic. - unsafe fn drop(handle: u32); - } - - impl Resource { - #[doc(hidden)] - pub unsafe fn from_handle(handle: u32) -> Self { - debug_assert!(handle != u32::MAX); - Self { - handle: AtomicU32::new(handle), - _marker: marker::PhantomData, - } - } - - /// Takes ownership of the handle owned by `resource`. - /// - /// Note that this ideally would be `into_handle` taking `Resource` by - /// ownership. The code generator does not enable that in all situations, - /// unfortunately, so this is provided instead. - /// - /// Also note that `take_handle` is in theory only ever called on values - /// owned by a generated function. For example a generated function might - /// take `Resource` as an argument but then call `take_handle` on a - /// reference to that argument. In that sense the dynamic nature of - /// `take_handle` should only be exposed internally to generated code, not - /// to user code. - #[doc(hidden)] - pub fn take_handle(resource: &Resource) -> u32 { - resource.handle.swap(u32::MAX, Relaxed) - } - - #[doc(hidden)] - pub fn handle(resource: &Resource) -> u32 { - resource.handle.load(Relaxed) - } - } - - impl fmt::Debug for Resource { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Resource") - .field("handle", &self.handle) - .finish() - } - } - - impl Drop for Resource { - fn drop(&mut self) { - unsafe { - match self.handle.load(Relaxed) { - // If this handle was "taken" then don't do anything in the - // destructor. - u32::MAX => {} - - // ... but otherwise do actually destroy it with the imported - // component model intrinsic as defined through `T`. - other => T::drop(other), - } - } - } - } - pub unsafe fn bool_lift(val: u8) -> bool { - if cfg!(debug_assertions) { - match val { - 0 => false, - 1 => true, - _ => panic!("invalid bool discriminant"), - } - } else { - val != 0 - } - } - pub use alloc_crate::alloc; - - pub fn as_i64(t: T) -> i64 { - t.as_i64() - } - - pub trait AsI64 { - fn as_i64(self) -> i64; - } - - impl<'a, T: Copy + AsI64> AsI64 for &'a T { - fn as_i64(self) -> i64 { - (*self).as_i64() - } - } - - impl AsI64 for i64 { - #[inline] - fn as_i64(self) -> i64 { - self as i64 - } - } - - impl AsI64 for u64 { - #[inline] - fn as_i64(self) -> i64 { - self as i64 - } - } - - pub fn as_i32(t: T) -> i32 { - t.as_i32() - } - - pub trait AsI32 { - fn as_i32(self) -> i32; - } - - impl<'a, T: Copy + AsI32> AsI32 for &'a T { - fn as_i32(self) -> i32 { - (*self).as_i32() - } - } - - impl AsI32 for i32 { - #[inline] - fn as_i32(self) -> i32 { - self as i32 - } - } - - impl AsI32 for u32 { - #[inline] - fn as_i32(self) -> i32 { - self as i32 - } - } - - impl AsI32 for i16 { - #[inline] - fn as_i32(self) -> i32 { - self as i32 - } - } - - impl AsI32 for u16 { - #[inline] - fn as_i32(self) -> i32 { - self as i32 - } - } - - impl AsI32 for i8 { - #[inline] - fn as_i32(self) -> i32 { - self as i32 - } - } - - impl AsI32 for u8 { - #[inline] - fn as_i32(self) -> i32 { - self as i32 - } - } - - impl AsI32 for char { - #[inline] - fn as_i32(self) -> i32 { - self as i32 - } - } - - impl AsI32 for usize { - #[inline] - fn as_i32(self) -> i32 { - self as i32 - } - } - - #[cfg(target_arch = "wasm32")] - pub fn run_ctors_once() { - wit_bindgen_rt::run_ctors_once(); - } - extern crate alloc as alloc_crate; -} - -/// Generates `#[no_mangle]` functions to export the specified type as the -/// root implementation of all generated traits. -/// -/// For more information see the documentation of `wit_bindgen::generate!`. -/// -/// ```rust -/// # macro_rules! export{ ($($t:tt)*) => (); } -/// # trait Guest {} -/// struct MyType; -/// -/// impl Guest for MyType { -/// // ... -/// } -/// -/// export!(MyType); -/// ``` -#[allow(unused_macros)] -#[doc(hidden)] - -macro_rules! __export_http_client_impl { - ($ty:ident) => (self::export!($ty with_types_in self);); - ($ty:ident with_types_in $($path_to_types_root:tt)*) => ( - $($path_to_types_root)*::exports::wasi::cli::run::__export_wasi_cli_run_0_2_0_cabi!($ty with_types_in $($path_to_types_root)*::exports::wasi::cli::run); - ) -} -#[doc(inline)] -pub(crate) use __export_http_client_impl as export; - -#[cfg(target_arch = "wasm32")] -#[link_section = "component-type:wit-bindgen:0.24.0:http-client:encoded world"] -#[doc(hidden)] -pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 10805] = *b"\ -\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xb3S\x01A\x02\x01AI\x01\ -B\x0a\x01o\x02ss\x01p\0\x01@\0\0\x01\x04\0\x0fget-environment\x01\x02\x01ps\x01@\ -\0\0\x03\x04\0\x0dget-arguments\x01\x04\x01ks\x01@\0\0\x05\x04\0\x0binitial-cwd\x01\ -\x06\x03\x01\x1awasi:cli/environment@0.2.0\x05\0\x01B\x03\x01j\0\0\x01@\x01\x06s\ -tatus\0\x01\0\x04\0\x04exit\x01\x01\x03\x01\x13wasi:cli/exit@0.2.0\x05\x01\x01B\x04\ -\x04\0\x05error\x03\x01\x01h\0\x01@\x01\x04self\x01\0s\x04\0\x1d[method]error.to\ --debug-string\x01\x02\x03\x01\x13wasi:io/error@0.2.0\x05\x02\x01B\x0a\x04\0\x08p\ -ollable\x03\x01\x01h\0\x01@\x01\x04self\x01\0\x7f\x04\0\x16[method]pollable.read\ -y\x01\x02\x01@\x01\x04self\x01\x01\0\x04\0\x16[method]pollable.block\x01\x03\x01\ -p\x01\x01py\x01@\x01\x02in\x04\0\x05\x04\0\x04poll\x01\x06\x03\x01\x12wasi:io/po\ -ll@0.2.0\x05\x03\x02\x03\0\x02\x05error\x02\x03\0\x03\x08pollable\x01B(\x02\x03\x02\ -\x01\x04\x04\0\x05error\x03\0\0\x02\x03\x02\x01\x05\x04\0\x08pollable\x03\0\x02\x01\ -i\x01\x01q\x02\x15last-operation-failed\x01\x04\0\x06closed\0\0\x04\0\x0cstream-\ -error\x03\0\x05\x04\0\x0cinput-stream\x03\x01\x04\0\x0doutput-stream\x03\x01\x01\ -h\x07\x01p}\x01j\x01\x0a\x01\x06\x01@\x02\x04self\x09\x03lenw\0\x0b\x04\0\x19[me\ -thod]input-stream.read\x01\x0c\x04\0\"[method]input-stream.blocking-read\x01\x0c\ -\x01j\x01w\x01\x06\x01@\x02\x04self\x09\x03lenw\0\x0d\x04\0\x19[method]input-str\ -eam.skip\x01\x0e\x04\0\"[method]input-stream.blocking-skip\x01\x0e\x01i\x03\x01@\ -\x01\x04self\x09\0\x0f\x04\0\x1e[method]input-stream.subscribe\x01\x10\x01h\x08\x01\ -@\x01\x04self\x11\0\x0d\x04\0![method]output-stream.check-write\x01\x12\x01j\0\x01\ -\x06\x01@\x02\x04self\x11\x08contents\x0a\0\x13\x04\0\x1b[method]output-stream.w\ -rite\x01\x14\x04\0.[method]output-stream.blocking-write-and-flush\x01\x14\x01@\x01\ -\x04self\x11\0\x13\x04\0\x1b[method]output-stream.flush\x01\x15\x04\0$[method]ou\ -tput-stream.blocking-flush\x01\x15\x01@\x01\x04self\x11\0\x0f\x04\0\x1f[method]o\ -utput-stream.subscribe\x01\x16\x01@\x02\x04self\x11\x03lenw\0\x13\x04\0\"[method\ -]output-stream.write-zeroes\x01\x17\x04\05[method]output-stream.blocking-write-z\ -eroes-and-flush\x01\x17\x01@\x03\x04self\x11\x03src\x09\x03lenw\0\x0d\x04\0\x1c[\ -method]output-stream.splice\x01\x18\x04\0%[method]output-stream.blocking-splice\x01\ -\x18\x03\x01\x15wasi:io/streams@0.2.0\x05\x06\x02\x03\0\x04\x0cinput-stream\x01B\ -\x05\x02\x03\x02\x01\x07\x04\0\x0cinput-stream\x03\0\0\x01i\x01\x01@\0\0\x02\x04\ -\0\x09get-stdin\x01\x03\x03\x01\x14wasi:cli/stdin@0.2.0\x05\x08\x02\x03\0\x04\x0d\ -output-stream\x01B\x05\x02\x03\x02\x01\x09\x04\0\x0doutput-stream\x03\0\0\x01i\x01\ -\x01@\0\0\x02\x04\0\x0aget-stdout\x01\x03\x03\x01\x15wasi:cli/stdout@0.2.0\x05\x0a\ -\x01B\x05\x02\x03\x02\x01\x09\x04\0\x0doutput-stream\x03\0\0\x01i\x01\x01@\0\0\x02\ -\x04\0\x0aget-stderr\x01\x03\x03\x01\x15wasi:cli/stderr@0.2.0\x05\x0b\x01B\x01\x04\ -\0\x0eterminal-input\x03\x01\x03\x01\x1dwasi:cli/terminal-input@0.2.0\x05\x0c\x01\ -B\x01\x04\0\x0fterminal-output\x03\x01\x03\x01\x1ewasi:cli/terminal-output@0.2.0\ -\x05\x0d\x02\x03\0\x08\x0eterminal-input\x01B\x06\x02\x03\x02\x01\x0e\x04\0\x0et\ -erminal-input\x03\0\0\x01i\x01\x01k\x02\x01@\0\0\x03\x04\0\x12get-terminal-stdin\ -\x01\x04\x03\x01\x1dwasi:cli/terminal-stdin@0.2.0\x05\x0f\x02\x03\0\x09\x0ftermi\ -nal-output\x01B\x06\x02\x03\x02\x01\x10\x04\0\x0fterminal-output\x03\0\0\x01i\x01\ -\x01k\x02\x01@\0\0\x03\x04\0\x13get-terminal-stdout\x01\x04\x03\x01\x1ewasi:cli/\ -terminal-stdout@0.2.0\x05\x11\x01B\x06\x02\x03\x02\x01\x10\x04\0\x0fterminal-out\ -put\x03\0\0\x01i\x01\x01k\x02\x01@\0\0\x03\x04\0\x13get-terminal-stderr\x01\x04\x03\ -\x01\x1ewasi:cli/terminal-stderr@0.2.0\x05\x12\x01B\x0f\x02\x03\x02\x01\x05\x04\0\ -\x08pollable\x03\0\0\x01w\x04\0\x07instant\x03\0\x02\x01w\x04\0\x08duration\x03\0\ -\x04\x01@\0\0\x03\x04\0\x03now\x01\x06\x01@\0\0\x05\x04\0\x0aresolution\x01\x07\x01\ -i\x01\x01@\x01\x04when\x03\0\x08\x04\0\x11subscribe-instant\x01\x09\x01@\x01\x04\ -when\x05\0\x08\x04\0\x12subscribe-duration\x01\x0a\x03\x01!wasi:clocks/monotonic\ --clock@0.2.0\x05\x13\x01B\x05\x01r\x02\x07secondsw\x0bnanosecondsy\x04\0\x08date\ -time\x03\0\0\x01@\0\0\x01\x04\0\x03now\x01\x02\x04\0\x0aresolution\x01\x02\x03\x01\ -\x1cwasi:clocks/wall-clock@0.2.0\x05\x14\x02\x03\0\x04\x05error\x02\x03\0\x0e\x08\ -datetime\x01Br\x02\x03\x02\x01\x07\x04\0\x0cinput-stream\x03\0\0\x02\x03\x02\x01\ -\x09\x04\0\x0doutput-stream\x03\0\x02\x02\x03\x02\x01\x15\x04\0\x05error\x03\0\x04\ -\x02\x03\x02\x01\x16\x04\0\x08datetime\x03\0\x06\x01w\x04\0\x08filesize\x03\0\x08\ -\x01m\x08\x07unknown\x0cblock-device\x10character-device\x09directory\x04fifo\x0d\ -symbolic-link\x0cregular-file\x06socket\x04\0\x0fdescriptor-type\x03\0\x0a\x01n\x06\ -\x04read\x05write\x13file-integrity-sync\x13data-integrity-sync\x14requested-wri\ -te-sync\x10mutate-directory\x04\0\x10descriptor-flags\x03\0\x0c\x01n\x01\x0esyml\ -ink-follow\x04\0\x0apath-flags\x03\0\x0e\x01n\x04\x06create\x09directory\x09excl\ -usive\x08truncate\x04\0\x0aopen-flags\x03\0\x10\x01w\x04\0\x0alink-count\x03\0\x12\ -\x01k\x07\x01r\x06\x04type\x0b\x0alink-count\x13\x04size\x09\x15data-access-time\ -stamp\x14\x1bdata-modification-timestamp\x14\x17status-change-timestamp\x14\x04\0\ -\x0fdescriptor-stat\x03\0\x15\x01q\x03\x09no-change\0\0\x03now\0\0\x09timestamp\x01\ -\x07\0\x04\0\x0dnew-timestamp\x03\0\x17\x01r\x02\x04type\x0b\x04names\x04\0\x0fd\ -irectory-entry\x03\0\x19\x01m%\x06access\x0bwould-block\x07already\x0ebad-descri\ -ptor\x04busy\x08deadlock\x05quota\x05exist\x0efile-too-large\x15illegal-byte-seq\ -uence\x0bin-progress\x0binterrupted\x07invalid\x02io\x0cis-directory\x04loop\x0e\ -too-many-links\x0cmessage-size\x0dname-too-long\x09no-device\x08no-entry\x07no-l\ -ock\x13insufficient-memory\x12insufficient-space\x0dnot-directory\x09not-empty\x0f\ -not-recoverable\x0bunsupported\x06no-tty\x0eno-such-device\x08overflow\x0dnot-pe\ -rmitted\x04pipe\x09read-only\x0cinvalid-seek\x0etext-file-busy\x0ccross-device\x04\ -\0\x0aerror-code\x03\0\x1b\x01m\x06\x06normal\x0asequential\x06random\x09will-ne\ -ed\x09dont-need\x08no-reuse\x04\0\x06advice\x03\0\x1d\x01r\x02\x05lowerw\x05uppe\ -rw\x04\0\x13metadata-hash-value\x03\0\x1f\x04\0\x0adescriptor\x03\x01\x04\0\x16d\ -irectory-entry-stream\x03\x01\x01h!\x01i\x01\x01j\x01$\x01\x1c\x01@\x02\x04self#\ -\x06offset\x09\0%\x04\0\"[method]descriptor.read-via-stream\x01&\x01i\x03\x01j\x01\ -'\x01\x1c\x01@\x02\x04self#\x06offset\x09\0(\x04\0#[method]descriptor.write-via-\ -stream\x01)\x01@\x01\x04self#\0(\x04\0$[method]descriptor.append-via-stream\x01*\ -\x01j\0\x01\x1c\x01@\x04\x04self#\x06offset\x09\x06length\x09\x06advice\x1e\0+\x04\ -\0\x19[method]descriptor.advise\x01,\x01@\x01\x04self#\0+\x04\0\x1c[method]descr\ -iptor.sync-data\x01-\x01j\x01\x0d\x01\x1c\x01@\x01\x04self#\0.\x04\0\x1c[method]\ -descriptor.get-flags\x01/\x01j\x01\x0b\x01\x1c\x01@\x01\x04self#\00\x04\0\x1b[me\ -thod]descriptor.get-type\x011\x01@\x02\x04self#\x04size\x09\0+\x04\0\x1b[method]\ -descriptor.set-size\x012\x01@\x03\x04self#\x15data-access-timestamp\x18\x1bdata-\ -modification-timestamp\x18\0+\x04\0\x1c[method]descriptor.set-times\x013\x01p}\x01\ -o\x024\x7f\x01j\x015\x01\x1c\x01@\x03\x04self#\x06length\x09\x06offset\x09\06\x04\ -\0\x17[method]descriptor.read\x017\x01j\x01\x09\x01\x1c\x01@\x03\x04self#\x06buf\ -fer4\x06offset\x09\08\x04\0\x18[method]descriptor.write\x019\x01i\"\x01j\x01:\x01\ -\x1c\x01@\x01\x04self#\0;\x04\0![method]descriptor.read-directory\x01<\x04\0\x17\ -[method]descriptor.sync\x01-\x01@\x02\x04self#\x04paths\0+\x04\0&[method]descrip\ -tor.create-directory-at\x01=\x01j\x01\x16\x01\x1c\x01@\x01\x04self#\0>\x04\0\x17\ -[method]descriptor.stat\x01?\x01@\x03\x04self#\x0apath-flags\x0f\x04paths\0>\x04\ -\0\x1a[method]descriptor.stat-at\x01@\x01@\x05\x04self#\x0apath-flags\x0f\x04pat\ -hs\x15data-access-timestamp\x18\x1bdata-modification-timestamp\x18\0+\x04\0\x1f[\ -method]descriptor.set-times-at\x01A\x01@\x05\x04self#\x0eold-path-flags\x0f\x08o\ -ld-paths\x0enew-descriptor#\x08new-paths\0+\x04\0\x1a[method]descriptor.link-at\x01\ -B\x01i!\x01j\x01\xc3\0\x01\x1c\x01@\x05\x04self#\x0apath-flags\x0f\x04paths\x0ao\ -pen-flags\x11\x05flags\x0d\0\xc4\0\x04\0\x1a[method]descriptor.open-at\x01E\x01j\ -\x01s\x01\x1c\x01@\x02\x04self#\x04paths\0\xc6\0\x04\0\x1e[method]descriptor.rea\ -dlink-at\x01G\x04\0&[method]descriptor.remove-directory-at\x01=\x01@\x04\x04self\ -#\x08old-paths\x0enew-descriptor#\x08new-paths\0+\x04\0\x1c[method]descriptor.re\ -name-at\x01H\x01@\x03\x04self#\x08old-paths\x08new-paths\0+\x04\0\x1d[method]des\ -criptor.symlink-at\x01I\x04\0![method]descriptor.unlink-file-at\x01=\x01@\x02\x04\ -self#\x05other#\0\x7f\x04\0![method]descriptor.is-same-object\x01J\x01j\x01\x20\x01\ -\x1c\x01@\x01\x04self#\0\xcb\0\x04\0\x20[method]descriptor.metadata-hash\x01L\x01\ -@\x03\x04self#\x0apath-flags\x0f\x04paths\0\xcb\0\x04\0#[method]descriptor.metad\ -ata-hash-at\x01M\x01h\"\x01k\x1a\x01j\x01\xcf\0\x01\x1c\x01@\x01\x04self\xce\0\0\ -\xd0\0\x04\03[method]directory-entry-stream.read-directory-entry\x01Q\x01h\x05\x01\ -k\x1c\x01@\x01\x03err\xd2\0\0\xd3\0\x04\0\x15filesystem-error-code\x01T\x03\x01\x1b\ -wasi:filesystem/types@0.2.0\x05\x17\x02\x03\0\x0f\x0adescriptor\x01B\x07\x02\x03\ -\x02\x01\x18\x04\0\x0adescriptor\x03\0\0\x01i\x01\x01o\x02\x02s\x01p\x03\x01@\0\0\ -\x04\x04\0\x0fget-directories\x01\x05\x03\x01\x1ewasi:filesystem/preopens@0.2.0\x05\ -\x19\x01B\x11\x04\0\x07network\x03\x01\x01m\x15\x07unknown\x0daccess-denied\x0dn\ -ot-supported\x10invalid-argument\x0dout-of-memory\x07timeout\x14concurrency-conf\ -lict\x0fnot-in-progress\x0bwould-block\x0dinvalid-state\x10new-socket-limit\x14a\ -ddress-not-bindable\x0eaddress-in-use\x12remote-unreachable\x12connection-refuse\ -d\x10connection-reset\x12connection-aborted\x12datagram-too-large\x11name-unreso\ -lvable\x1atemporary-resolver-failure\x1apermanent-resolver-failure\x04\0\x0aerro\ -r-code\x03\0\x01\x01m\x02\x04ipv4\x04ipv6\x04\0\x11ip-address-family\x03\0\x03\x01\ -o\x04}}}}\x04\0\x0cipv4-address\x03\0\x05\x01o\x08{{{{{{{{\x04\0\x0cipv6-address\ -\x03\0\x07\x01q\x02\x04ipv4\x01\x06\0\x04ipv6\x01\x08\0\x04\0\x0aip-address\x03\0\ -\x09\x01r\x02\x04port{\x07address\x06\x04\0\x13ipv4-socket-address\x03\0\x0b\x01\ -r\x04\x04port{\x09flow-infoy\x07address\x08\x08scope-idy\x04\0\x13ipv6-socket-ad\ -dress\x03\0\x0d\x01q\x02\x04ipv4\x01\x0c\0\x04ipv6\x01\x0e\0\x04\0\x11ip-socket-\ -address\x03\0\x0f\x03\x01\x1awasi:sockets/network@0.2.0\x05\x1a\x02\x03\0\x11\x07\ -network\x01B\x05\x02\x03\x02\x01\x1b\x04\0\x07network\x03\0\0\x01i\x01\x01@\0\0\x02\ -\x04\0\x10instance-network\x01\x03\x03\x01#wasi:sockets/instance-network@0.2.0\x05\ -\x1c\x02\x03\0\x11\x0aerror-code\x02\x03\0\x11\x11ip-socket-address\x02\x03\0\x11\ -\x11ip-address-family\x01BD\x02\x03\x02\x01\x05\x04\0\x08pollable\x03\0\0\x02\x03\ -\x02\x01\x1b\x04\0\x07network\x03\0\x02\x02\x03\x02\x01\x1d\x04\0\x0aerror-code\x03\ -\0\x04\x02\x03\x02\x01\x1e\x04\0\x11ip-socket-address\x03\0\x06\x02\x03\x02\x01\x1f\ -\x04\0\x11ip-address-family\x03\0\x08\x01p}\x01r\x02\x04data\x0a\x0eremote-addre\ -ss\x07\x04\0\x11incoming-datagram\x03\0\x0b\x01k\x07\x01r\x02\x04data\x0a\x0erem\ -ote-address\x0d\x04\0\x11outgoing-datagram\x03\0\x0e\x04\0\x0audp-socket\x03\x01\ -\x04\0\x18incoming-datagram-stream\x03\x01\x04\0\x18outgoing-datagram-stream\x03\ -\x01\x01h\x10\x01h\x03\x01j\0\x01\x05\x01@\x03\x04self\x13\x07network\x14\x0dloc\ -al-address\x07\0\x15\x04\0\x1d[method]udp-socket.start-bind\x01\x16\x01@\x01\x04\ -self\x13\0\x15\x04\0\x1e[method]udp-socket.finish-bind\x01\x17\x01i\x11\x01i\x12\ -\x01o\x02\x18\x19\x01j\x01\x1a\x01\x05\x01@\x02\x04self\x13\x0eremote-address\x0d\ -\0\x1b\x04\0\x19[method]udp-socket.stream\x01\x1c\x01j\x01\x07\x01\x05\x01@\x01\x04\ -self\x13\0\x1d\x04\0\x20[method]udp-socket.local-address\x01\x1e\x04\0![method]u\ -dp-socket.remote-address\x01\x1e\x01@\x01\x04self\x13\0\x09\x04\0![method]udp-so\ -cket.address-family\x01\x1f\x01j\x01}\x01\x05\x01@\x01\x04self\x13\0\x20\x04\0$[\ -method]udp-socket.unicast-hop-limit\x01!\x01@\x02\x04self\x13\x05value}\0\x15\x04\ -\0([method]udp-socket.set-unicast-hop-limit\x01\"\x01j\x01w\x01\x05\x01@\x01\x04\ -self\x13\0#\x04\0&[method]udp-socket.receive-buffer-size\x01$\x01@\x02\x04self\x13\ -\x05valuew\0\x15\x04\0*[method]udp-socket.set-receive-buffer-size\x01%\x04\0#[me\ -thod]udp-socket.send-buffer-size\x01$\x04\0'[method]udp-socket.set-send-buffer-s\ -ize\x01%\x01i\x01\x01@\x01\x04self\x13\0&\x04\0\x1c[method]udp-socket.subscribe\x01\ -'\x01h\x11\x01p\x0c\x01j\x01)\x01\x05\x01@\x02\x04self(\x0bmax-resultsw\0*\x04\0\ -([method]incoming-datagram-stream.receive\x01+\x01@\x01\x04self(\0&\x04\0*[metho\ -d]incoming-datagram-stream.subscribe\x01,\x01h\x12\x01@\x01\x04self-\0#\x04\0+[m\ -ethod]outgoing-datagram-stream.check-send\x01.\x01p\x0f\x01@\x02\x04self-\x09dat\ -agrams/\0#\x04\0%[method]outgoing-datagram-stream.send\x010\x01@\x01\x04self-\0&\ -\x04\0*[method]outgoing-datagram-stream.subscribe\x011\x03\x01\x16wasi:sockets/u\ -dp@0.2.0\x05\x20\x02\x03\0\x13\x0audp-socket\x01B\x0c\x02\x03\x02\x01\x1b\x04\0\x07\ -network\x03\0\0\x02\x03\x02\x01\x1d\x04\0\x0aerror-code\x03\0\x02\x02\x03\x02\x01\ -\x1f\x04\0\x11ip-address-family\x03\0\x04\x02\x03\x02\x01!\x04\0\x0audp-socket\x03\ -\0\x06\x01i\x07\x01j\x01\x08\x01\x03\x01@\x01\x0eaddress-family\x05\0\x09\x04\0\x11\ -create-udp-socket\x01\x0a\x03\x01$wasi:sockets/udp-create-socket@0.2.0\x05\"\x02\ -\x03\0\x0d\x08duration\x01BT\x02\x03\x02\x01\x07\x04\0\x0cinput-stream\x03\0\0\x02\ -\x03\x02\x01\x09\x04\0\x0doutput-stream\x03\0\x02\x02\x03\x02\x01\x05\x04\0\x08p\ -ollable\x03\0\x04\x02\x03\x02\x01#\x04\0\x08duration\x03\0\x06\x02\x03\x02\x01\x1b\ -\x04\0\x07network\x03\0\x08\x02\x03\x02\x01\x1d\x04\0\x0aerror-code\x03\0\x0a\x02\ -\x03\x02\x01\x1e\x04\0\x11ip-socket-address\x03\0\x0c\x02\x03\x02\x01\x1f\x04\0\x11\ -ip-address-family\x03\0\x0e\x01m\x03\x07receive\x04send\x04both\x04\0\x0dshutdow\ -n-type\x03\0\x10\x04\0\x0atcp-socket\x03\x01\x01h\x12\x01h\x09\x01j\0\x01\x0b\x01\ -@\x03\x04self\x13\x07network\x14\x0dlocal-address\x0d\0\x15\x04\0\x1d[method]tcp\ --socket.start-bind\x01\x16\x01@\x01\x04self\x13\0\x15\x04\0\x1e[method]tcp-socke\ -t.finish-bind\x01\x17\x01@\x03\x04self\x13\x07network\x14\x0eremote-address\x0d\0\ -\x15\x04\0\x20[method]tcp-socket.start-connect\x01\x18\x01i\x01\x01i\x03\x01o\x02\ -\x19\x1a\x01j\x01\x1b\x01\x0b\x01@\x01\x04self\x13\0\x1c\x04\0![method]tcp-socke\ -t.finish-connect\x01\x1d\x04\0\x1f[method]tcp-socket.start-listen\x01\x17\x04\0\x20\ -[method]tcp-socket.finish-listen\x01\x17\x01i\x12\x01o\x03\x1e\x19\x1a\x01j\x01\x1f\ -\x01\x0b\x01@\x01\x04self\x13\0\x20\x04\0\x19[method]tcp-socket.accept\x01!\x01j\ -\x01\x0d\x01\x0b\x01@\x01\x04self\x13\0\"\x04\0\x20[method]tcp-socket.local-addr\ -ess\x01#\x04\0![method]tcp-socket.remote-address\x01#\x01@\x01\x04self\x13\0\x7f\ -\x04\0\x1f[method]tcp-socket.is-listening\x01$\x01@\x01\x04self\x13\0\x0f\x04\0!\ -[method]tcp-socket.address-family\x01%\x01@\x02\x04self\x13\x05valuew\0\x15\x04\0\ -*[method]tcp-socket.set-listen-backlog-size\x01&\x01j\x01\x7f\x01\x0b\x01@\x01\x04\ -self\x13\0'\x04\0%[method]tcp-socket.keep-alive-enabled\x01(\x01@\x02\x04self\x13\ -\x05value\x7f\0\x15\x04\0)[method]tcp-socket.set-keep-alive-enabled\x01)\x01j\x01\ -\x07\x01\x0b\x01@\x01\x04self\x13\0*\x04\0'[method]tcp-socket.keep-alive-idle-ti\ -me\x01+\x01@\x02\x04self\x13\x05value\x07\0\x15\x04\0+[method]tcp-socket.set-kee\ -p-alive-idle-time\x01,\x04\0&[method]tcp-socket.keep-alive-interval\x01+\x04\0*[\ -method]tcp-socket.set-keep-alive-interval\x01,\x01j\x01y\x01\x0b\x01@\x01\x04sel\ -f\x13\0-\x04\0#[method]tcp-socket.keep-alive-count\x01.\x01@\x02\x04self\x13\x05\ -valuey\0\x15\x04\0'[method]tcp-socket.set-keep-alive-count\x01/\x01j\x01}\x01\x0b\ -\x01@\x01\x04self\x13\00\x04\0\x1c[method]tcp-socket.hop-limit\x011\x01@\x02\x04\ -self\x13\x05value}\0\x15\x04\0\x20[method]tcp-socket.set-hop-limit\x012\x01j\x01\ -w\x01\x0b\x01@\x01\x04self\x13\03\x04\0&[method]tcp-socket.receive-buffer-size\x01\ -4\x04\0*[method]tcp-socket.set-receive-buffer-size\x01&\x04\0#[method]tcp-socket\ -.send-buffer-size\x014\x04\0'[method]tcp-socket.set-send-buffer-size\x01&\x01i\x05\ -\x01@\x01\x04self\x13\05\x04\0\x1c[method]tcp-socket.subscribe\x016\x01@\x02\x04\ -self\x13\x0dshutdown-type\x11\0\x15\x04\0\x1b[method]tcp-socket.shutdown\x017\x03\ -\x01\x16wasi:sockets/tcp@0.2.0\x05$\x02\x03\0\x15\x0atcp-socket\x01B\x0c\x02\x03\ -\x02\x01\x1b\x04\0\x07network\x03\0\0\x02\x03\x02\x01\x1d\x04\0\x0aerror-code\x03\ -\0\x02\x02\x03\x02\x01\x1f\x04\0\x11ip-address-family\x03\0\x04\x02\x03\x02\x01%\ -\x04\0\x0atcp-socket\x03\0\x06\x01i\x07\x01j\x01\x08\x01\x03\x01@\x01\x0eaddress\ --family\x05\0\x09\x04\0\x11create-tcp-socket\x01\x0a\x03\x01$wasi:sockets/tcp-cr\ -eate-socket@0.2.0\x05&\x02\x03\0\x11\x0aip-address\x01B\x16\x02\x03\x02\x01\x05\x04\ -\0\x08pollable\x03\0\0\x02\x03\x02\x01\x1b\x04\0\x07network\x03\0\x02\x02\x03\x02\ -\x01\x1d\x04\0\x0aerror-code\x03\0\x04\x02\x03\x02\x01'\x04\0\x0aip-address\x03\0\ -\x06\x04\0\x16resolve-address-stream\x03\x01\x01h\x08\x01k\x07\x01j\x01\x0a\x01\x05\ -\x01@\x01\x04self\x09\0\x0b\x04\03[method]resolve-address-stream.resolve-next-ad\ -dress\x01\x0c\x01i\x01\x01@\x01\x04self\x09\0\x0d\x04\0([method]resolve-address-\ -stream.subscribe\x01\x0e\x01h\x03\x01i\x08\x01j\x01\x10\x01\x05\x01@\x02\x07netw\ -ork\x0f\x04names\0\x11\x04\0\x11resolve-addresses\x01\x12\x03\x01!wasi:sockets/i\ -p-name-lookup@0.2.0\x05(\x01B\x05\x01p}\x01@\x01\x03lenw\0\0\x04\0\x10get-random\ --bytes\x01\x01\x01@\0\0w\x04\0\x0eget-random-u64\x01\x02\x03\x01\x18wasi:random/\ -random@0.2.0\x05)\x01B\x05\x01p}\x01@\x01\x03lenw\0\0\x04\0\x19get-insecure-rand\ -om-bytes\x01\x01\x01@\0\0w\x04\0\x17get-insecure-random-u64\x01\x02\x03\x01\x1aw\ -asi:random/insecure@0.2.0\x05*\x01B\x03\x01o\x02ww\x01@\0\0\0\x04\0\x0dinsecure-\ -seed\x01\x01\x03\x01\x1fwasi:random/insecure-seed@0.2.0\x05+\x01B\x03\x01j\0\0\x01\ -@\0\0\0\x04\0\x03run\x01\x01\x04\x01\x12wasi:cli/run@0.2.0\x05,\x04\x012iawia002\ -:wasi-http-client-test-program/http-client\x04\0\x0b\x11\x01\0\x0bhttp-client\x03\ -\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.202.0\x10wit-\ -bindgen-rust\x060.24.0"; - -#[inline(never)] -#[doc(hidden)] -#[cfg(target_arch = "wasm32")] -pub fn __link_custom_section_describing_imports() { - wit_bindgen_rt::maybe_link_cabi_realloc(); -} diff --git a/tests/program/src/lib.rs b/tests/program/src/lib.rs deleted file mode 100644 index cf2f248..0000000 --- a/tests/program/src/lib.rs +++ /dev/null @@ -1,112 +0,0 @@ -#[allow(warnings)] -mod bindings; - -use bindings::exports::wasi::cli::run::Guest; -use serde::Deserialize; -use std::collections::HashMap; -use std::time::Duration; -use wasi_http_client::Client; - -struct Component; - -bindings::export!(Component with_types_in bindings); - -#[derive(Debug, Deserialize)] -#[allow(dead_code)] -struct Data { - origin: String, - url: String, -} - -impl Guest for Component { - fn run() -> Result<(), ()> { - // get with query - let resp = Client::new() - .get("https://httpbin.org/get?a=b") - .headers([("Content-Type", "application/json"), ("Accept", "*/*")]) - .send() - .unwrap(); - println!( - "GET https://httpbin.org/get, status code: {}, body:\n{}", - resp.status(), - String::from_utf8(resp.body().unwrap()).unwrap() - ); - - // get with json response - let resp = Client::new().get("https://httpbin.org/get").send().unwrap(); - let status = resp.status(); - let json_data = resp.json::().unwrap(); - println!( - "GET https://httpbin.org/get, status code: {}, body:\n{:?}\n", - status, json_data, - ); - - // play with the response chunk - let resp = Client::new() - .get("https://httpbin.org/range/20") - .query(&[("duration", "5"), ("chunk_size", "10")]) - .send() - .unwrap(); - println!( - "GET https://httpbin.org/range, status code: {}, body:", - resp.status() - ); - while let Some(chunk) = resp.chunk(1024).unwrap() { - println!("{}", String::from_utf8(chunk).unwrap()); - } - println!(); - - // post with json data - let resp = Client::new() - .post("https://httpbin.org/post") - .json(&HashMap::from([("data", "hello")])) - .connect_timeout(Duration::from_secs(5)) - .send() - .unwrap(); - println!( - "POST https://httpbin.org/post, status code: {}, body:\n{}", - resp.status(), - String::from_utf8(resp.body().unwrap()).unwrap() - ); - - // post with form data - let resp = Client::new() - .post("https://httpbin.org/post") - .form(&[("a", "b"), ("c", "")]) - .connect_timeout(Duration::from_secs(5)) - .send() - .unwrap(); - println!( - "POST https://httpbin.org/post, status code: {}, body:\n{}", - resp.status(), - String::from_utf8(resp.body().unwrap()).unwrap() - ); - - // post with file form data - let resp = Client::new() - .post("https://httpbin.org/post") - .header("Content-Type", "multipart/form-data; boundary=boundary") - .body( - "--boundary -Content-Disposition: form-data; name=field1 - -value1 ---boundary -Content-Disposition: form-data; name=field2; filename=file.txt -Content-Type: text/plain - -hello ---boundary--" - .as_bytes(), - ) - .connect_timeout(Duration::from_secs(5)) - .send() - .unwrap(); - println!( - "POST https://httpbin.org/post, status code: {}, body:\n{}", - resp.status(), - String::from_utf8(resp.body().unwrap()).unwrap() - ); - Ok(()) - } -} diff --git a/tests/program/wit/deps/cli/command.wit b/tests/program/wit/deps/cli/command.wit deleted file mode 100644 index d8005bd..0000000 --- a/tests/program/wit/deps/cli/command.wit +++ /dev/null @@ -1,7 +0,0 @@ -package wasi:cli@0.2.0; - -world command { - include imports; - - export run; -} diff --git a/tests/program/wit/deps/cli/environment.wit b/tests/program/wit/deps/cli/environment.wit deleted file mode 100644 index 7006523..0000000 --- a/tests/program/wit/deps/cli/environment.wit +++ /dev/null @@ -1,18 +0,0 @@ -interface environment { - /// Get the POSIX-style environment variables. - /// - /// Each environment variable is provided as a pair of string variable names - /// and string value. - /// - /// Morally, these are a value import, but until value imports are available - /// in the component model, this import function should return the same - /// values each time it is called. - get-environment: func() -> list>; - - /// Get the POSIX-style arguments to the program. - get-arguments: func() -> list; - - /// Return a path that programs should use as their initial current working - /// directory, interpreting `.` as shorthand for this. - initial-cwd: func() -> option; -} diff --git a/tests/program/wit/deps/cli/exit.wit b/tests/program/wit/deps/cli/exit.wit deleted file mode 100644 index d0c2b82..0000000 --- a/tests/program/wit/deps/cli/exit.wit +++ /dev/null @@ -1,4 +0,0 @@ -interface exit { - /// Exit the current instance and any linked instances. - exit: func(status: result); -} diff --git a/tests/program/wit/deps/cli/imports.wit b/tests/program/wit/deps/cli/imports.wit deleted file mode 100644 index 083b84a..0000000 --- a/tests/program/wit/deps/cli/imports.wit +++ /dev/null @@ -1,20 +0,0 @@ -package wasi:cli@0.2.0; - -world imports { - include wasi:clocks/imports@0.2.0; - include wasi:filesystem/imports@0.2.0; - include wasi:sockets/imports@0.2.0; - include wasi:random/imports@0.2.0; - include wasi:io/imports@0.2.0; - - import environment; - import exit; - import stdin; - import stdout; - import stderr; - import terminal-input; - import terminal-output; - import terminal-stdin; - import terminal-stdout; - import terminal-stderr; -} diff --git a/tests/program/wit/deps/cli/run.wit b/tests/program/wit/deps/cli/run.wit deleted file mode 100644 index a70ee8c..0000000 --- a/tests/program/wit/deps/cli/run.wit +++ /dev/null @@ -1,4 +0,0 @@ -interface run { - /// Run the program. - run: func() -> result; -} diff --git a/tests/program/wit/deps/cli/stdio.wit b/tests/program/wit/deps/cli/stdio.wit deleted file mode 100644 index 31ef35b..0000000 --- a/tests/program/wit/deps/cli/stdio.wit +++ /dev/null @@ -1,17 +0,0 @@ -interface stdin { - use wasi:io/streams@0.2.0.{input-stream}; - - get-stdin: func() -> input-stream; -} - -interface stdout { - use wasi:io/streams@0.2.0.{output-stream}; - - get-stdout: func() -> output-stream; -} - -interface stderr { - use wasi:io/streams@0.2.0.{output-stream}; - - get-stderr: func() -> output-stream; -} diff --git a/tests/program/wit/deps/cli/terminal.wit b/tests/program/wit/deps/cli/terminal.wit deleted file mode 100644 index 38c724e..0000000 --- a/tests/program/wit/deps/cli/terminal.wit +++ /dev/null @@ -1,49 +0,0 @@ -/// Terminal input. -/// -/// In the future, this may include functions for disabling echoing, -/// disabling input buffering so that keyboard events are sent through -/// immediately, querying supported features, and so on. -interface terminal-input { - /// The input side of a terminal. - resource terminal-input; -} - -/// Terminal output. -/// -/// In the future, this may include functions for querying the terminal -/// size, being notified of terminal size changes, querying supported -/// features, and so on. -interface terminal-output { - /// The output side of a terminal. - resource terminal-output; -} - -/// An interface providing an optional `terminal-input` for stdin as a -/// link-time authority. -interface terminal-stdin { - use terminal-input.{terminal-input}; - - /// If stdin is connected to a terminal, return a `terminal-input` handle - /// allowing further interaction with it. - get-terminal-stdin: func() -> option; -} - -/// An interface providing an optional `terminal-output` for stdout as a -/// link-time authority. -interface terminal-stdout { - use terminal-output.{terminal-output}; - - /// If stdout is connected to a terminal, return a `terminal-output` handle - /// allowing further interaction with it. - get-terminal-stdout: func() -> option; -} - -/// An interface providing an optional `terminal-output` for stderr as a -/// link-time authority. -interface terminal-stderr { - use terminal-output.{terminal-output}; - - /// If stderr is connected to a terminal, return a `terminal-output` handle - /// allowing further interaction with it. - get-terminal-stderr: func() -> option; -} diff --git a/tests/program/wit/deps/clocks/monotonic-clock.wit b/tests/program/wit/deps/clocks/monotonic-clock.wit deleted file mode 100644 index 4e4dc3a..0000000 --- a/tests/program/wit/deps/clocks/monotonic-clock.wit +++ /dev/null @@ -1,45 +0,0 @@ -package wasi:clocks@0.2.0; -/// WASI Monotonic Clock is a clock API intended to let users measure elapsed -/// time. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -/// -/// A monotonic clock is a clock which has an unspecified initial value, and -/// successive reads of the clock will produce non-decreasing values. -/// -/// It is intended for measuring elapsed time. -interface monotonic-clock { - use wasi:io/poll@0.2.0.{pollable}; - - /// An instant in time, in nanoseconds. An instant is relative to an - /// unspecified initial value, and can only be compared to instances from - /// the same monotonic-clock. - type instant = u64; - - /// A duration of time, in nanoseconds. - type duration = u64; - - /// Read the current value of the clock. - /// - /// The clock is monotonic, therefore calling this function repeatedly will - /// produce a sequence of non-decreasing values. - now: func() -> instant; - - /// Query the resolution of the clock. Returns the duration of time - /// corresponding to a clock tick. - resolution: func() -> duration; - - /// Create a `pollable` which will resolve once the specified instant - /// occured. - subscribe-instant: func( - when: instant, - ) -> pollable; - - /// Create a `pollable` which will resolve once the given duration has - /// elapsed, starting at the time at which this function was called. - /// occured. - subscribe-duration: func( - when: duration, - ) -> pollable; -} diff --git a/tests/program/wit/deps/clocks/wall-clock.wit b/tests/program/wit/deps/clocks/wall-clock.wit deleted file mode 100644 index 440ca0f..0000000 --- a/tests/program/wit/deps/clocks/wall-clock.wit +++ /dev/null @@ -1,42 +0,0 @@ -package wasi:clocks@0.2.0; -/// WASI Wall Clock is a clock API intended to let users query the current -/// time. The name "wall" makes an analogy to a "clock on the wall", which -/// is not necessarily monotonic as it may be reset. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -/// -/// A wall clock is a clock which measures the date and time according to -/// some external reference. -/// -/// External references may be reset, so this clock is not necessarily -/// monotonic, making it unsuitable for measuring elapsed time. -/// -/// It is intended for reporting the current date and time for humans. -interface wall-clock { - /// A time and date in seconds plus nanoseconds. - record datetime { - seconds: u64, - nanoseconds: u32, - } - - /// Read the current value of the clock. - /// - /// This clock is not monotonic, therefore calling this function repeatedly - /// will not necessarily produce a sequence of non-decreasing values. - /// - /// The returned timestamps represent the number of seconds since - /// 1970-01-01T00:00:00Z, also known as [POSIX's Seconds Since the Epoch], - /// also known as [Unix Time]. - /// - /// The nanoseconds field of the output is always less than 1000000000. - /// - /// [POSIX's Seconds Since the Epoch]: https://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap04.html#tag_21_04_16 - /// [Unix Time]: https://en.wikipedia.org/wiki/Unix_time - now: func() -> datetime; - - /// Query the resolution of the clock. - /// - /// The nanoseconds field of the output is always less than 1000000000. - resolution: func() -> datetime; -} diff --git a/tests/program/wit/deps/clocks/world.wit b/tests/program/wit/deps/clocks/world.wit deleted file mode 100644 index c022457..0000000 --- a/tests/program/wit/deps/clocks/world.wit +++ /dev/null @@ -1,6 +0,0 @@ -package wasi:clocks@0.2.0; - -world imports { - import monotonic-clock; - import wall-clock; -} diff --git a/tests/program/wit/deps/filesystem/preopens.wit b/tests/program/wit/deps/filesystem/preopens.wit deleted file mode 100644 index da801f6..0000000 --- a/tests/program/wit/deps/filesystem/preopens.wit +++ /dev/null @@ -1,8 +0,0 @@ -package wasi:filesystem@0.2.0; - -interface preopens { - use types.{descriptor}; - - /// Return the set of preopened directories, and their path. - get-directories: func() -> list>; -} diff --git a/tests/program/wit/deps/filesystem/types.wit b/tests/program/wit/deps/filesystem/types.wit deleted file mode 100644 index 11108fc..0000000 --- a/tests/program/wit/deps/filesystem/types.wit +++ /dev/null @@ -1,634 +0,0 @@ -package wasi:filesystem@0.2.0; -/// WASI filesystem is a filesystem API primarily intended to let users run WASI -/// programs that access their files on their existing filesystems, without -/// significant overhead. -/// -/// It is intended to be roughly portable between Unix-family platforms and -/// Windows, though it does not hide many of the major differences. -/// -/// Paths are passed as interface-type `string`s, meaning they must consist of -/// a sequence of Unicode Scalar Values (USVs). Some filesystems may contain -/// paths which are not accessible by this API. -/// -/// The directory separator in WASI is always the forward-slash (`/`). -/// -/// All paths in WASI are relative paths, and are interpreted relative to a -/// `descriptor` referring to a base directory. If a `path` argument to any WASI -/// function starts with `/`, or if any step of resolving a `path`, including -/// `..` and symbolic link steps, reaches a directory outside of the base -/// directory, or reaches a symlink to an absolute or rooted path in the -/// underlying filesystem, the function fails with `error-code::not-permitted`. -/// -/// For more information about WASI path resolution and sandboxing, see -/// [WASI filesystem path resolution]. -/// -/// [WASI filesystem path resolution]: https://github.com/WebAssembly/wasi-filesystem/blob/main/path-resolution.md -interface types { - use wasi:io/streams@0.2.0.{input-stream, output-stream, error}; - use wasi:clocks/wall-clock@0.2.0.{datetime}; - - /// File size or length of a region within a file. - type filesize = u64; - - /// The type of a filesystem object referenced by a descriptor. - /// - /// Note: This was called `filetype` in earlier versions of WASI. - enum descriptor-type { - /// The type of the descriptor or file is unknown or is different from - /// any of the other types specified. - unknown, - /// The descriptor refers to a block device inode. - block-device, - /// The descriptor refers to a character device inode. - character-device, - /// The descriptor refers to a directory inode. - directory, - /// The descriptor refers to a named pipe. - fifo, - /// The file refers to a symbolic link inode. - symbolic-link, - /// The descriptor refers to a regular file inode. - regular-file, - /// The descriptor refers to a socket. - socket, - } - - /// Descriptor flags. - /// - /// Note: This was called `fdflags` in earlier versions of WASI. - flags descriptor-flags { - /// Read mode: Data can be read. - read, - /// Write mode: Data can be written to. - write, - /// Request that writes be performed according to synchronized I/O file - /// integrity completion. The data stored in the file and the file's - /// metadata are synchronized. This is similar to `O_SYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - file-integrity-sync, - /// Request that writes be performed according to synchronized I/O data - /// integrity completion. Only the data stored in the file is - /// synchronized. This is similar to `O_DSYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - data-integrity-sync, - /// Requests that reads be performed at the same level of integrety - /// requested for writes. This is similar to `O_RSYNC` in POSIX. - /// - /// The precise semantics of this operation have not yet been defined for - /// WASI. At this time, it should be interpreted as a request, and not a - /// requirement. - requested-write-sync, - /// Mutating directories mode: Directory contents may be mutated. - /// - /// When this flag is unset on a descriptor, operations using the - /// descriptor which would create, rename, delete, modify the data or - /// metadata of filesystem objects, or obtain another handle which - /// would permit any of those, shall fail with `error-code::read-only` if - /// they would otherwise succeed. - /// - /// This may only be set on directories. - mutate-directory, - } - - /// File attributes. - /// - /// Note: This was called `filestat` in earlier versions of WASI. - record descriptor-stat { - /// File type. - %type: descriptor-type, - /// Number of hard links to the file. - link-count: link-count, - /// For regular files, the file size in bytes. For symbolic links, the - /// length in bytes of the pathname contained in the symbolic link. - size: filesize, - /// Last data access timestamp. - /// - /// If the `option` is none, the platform doesn't maintain an access - /// timestamp for this file. - data-access-timestamp: option, - /// Last data modification timestamp. - /// - /// If the `option` is none, the platform doesn't maintain a - /// modification timestamp for this file. - data-modification-timestamp: option, - /// Last file status-change timestamp. - /// - /// If the `option` is none, the platform doesn't maintain a - /// status-change timestamp for this file. - status-change-timestamp: option, - } - - /// Flags determining the method of how paths are resolved. - flags path-flags { - /// As long as the resolved path corresponds to a symbolic link, it is - /// expanded. - symlink-follow, - } - - /// Open flags used by `open-at`. - flags open-flags { - /// Create file if it does not exist, similar to `O_CREAT` in POSIX. - create, - /// Fail if not a directory, similar to `O_DIRECTORY` in POSIX. - directory, - /// Fail if file already exists, similar to `O_EXCL` in POSIX. - exclusive, - /// Truncate file to size 0, similar to `O_TRUNC` in POSIX. - truncate, - } - - /// Number of hard links to an inode. - type link-count = u64; - - /// When setting a timestamp, this gives the value to set it to. - variant new-timestamp { - /// Leave the timestamp set to its previous value. - no-change, - /// Set the timestamp to the current time of the system clock associated - /// with the filesystem. - now, - /// Set the timestamp to the given value. - timestamp(datetime), - } - - /// A directory entry. - record directory-entry { - /// The type of the file referred to by this directory entry. - %type: descriptor-type, - - /// The name of the object. - name: string, - } - - /// Error codes returned by functions, similar to `errno` in POSIX. - /// Not all of these error codes are returned by the functions provided by this - /// API; some are used in higher-level library layers, and others are provided - /// merely for alignment with POSIX. - enum error-code { - /// Permission denied, similar to `EACCES` in POSIX. - access, - /// Resource unavailable, or operation would block, similar to `EAGAIN` and `EWOULDBLOCK` in POSIX. - would-block, - /// Connection already in progress, similar to `EALREADY` in POSIX. - already, - /// Bad descriptor, similar to `EBADF` in POSIX. - bad-descriptor, - /// Device or resource busy, similar to `EBUSY` in POSIX. - busy, - /// Resource deadlock would occur, similar to `EDEADLK` in POSIX. - deadlock, - /// Storage quota exceeded, similar to `EDQUOT` in POSIX. - quota, - /// File exists, similar to `EEXIST` in POSIX. - exist, - /// File too large, similar to `EFBIG` in POSIX. - file-too-large, - /// Illegal byte sequence, similar to `EILSEQ` in POSIX. - illegal-byte-sequence, - /// Operation in progress, similar to `EINPROGRESS` in POSIX. - in-progress, - /// Interrupted function, similar to `EINTR` in POSIX. - interrupted, - /// Invalid argument, similar to `EINVAL` in POSIX. - invalid, - /// I/O error, similar to `EIO` in POSIX. - io, - /// Is a directory, similar to `EISDIR` in POSIX. - is-directory, - /// Too many levels of symbolic links, similar to `ELOOP` in POSIX. - loop, - /// Too many links, similar to `EMLINK` in POSIX. - too-many-links, - /// Message too large, similar to `EMSGSIZE` in POSIX. - message-size, - /// Filename too long, similar to `ENAMETOOLONG` in POSIX. - name-too-long, - /// No such device, similar to `ENODEV` in POSIX. - no-device, - /// No such file or directory, similar to `ENOENT` in POSIX. - no-entry, - /// No locks available, similar to `ENOLCK` in POSIX. - no-lock, - /// Not enough space, similar to `ENOMEM` in POSIX. - insufficient-memory, - /// No space left on device, similar to `ENOSPC` in POSIX. - insufficient-space, - /// Not a directory or a symbolic link to a directory, similar to `ENOTDIR` in POSIX. - not-directory, - /// Directory not empty, similar to `ENOTEMPTY` in POSIX. - not-empty, - /// State not recoverable, similar to `ENOTRECOVERABLE` in POSIX. - not-recoverable, - /// Not supported, similar to `ENOTSUP` and `ENOSYS` in POSIX. - unsupported, - /// Inappropriate I/O control operation, similar to `ENOTTY` in POSIX. - no-tty, - /// No such device or address, similar to `ENXIO` in POSIX. - no-such-device, - /// Value too large to be stored in data type, similar to `EOVERFLOW` in POSIX. - overflow, - /// Operation not permitted, similar to `EPERM` in POSIX. - not-permitted, - /// Broken pipe, similar to `EPIPE` in POSIX. - pipe, - /// Read-only file system, similar to `EROFS` in POSIX. - read-only, - /// Invalid seek, similar to `ESPIPE` in POSIX. - invalid-seek, - /// Text file busy, similar to `ETXTBSY` in POSIX. - text-file-busy, - /// Cross-device link, similar to `EXDEV` in POSIX. - cross-device, - } - - /// File or memory access pattern advisory information. - enum advice { - /// The application has no advice to give on its behavior with respect - /// to the specified data. - normal, - /// The application expects to access the specified data sequentially - /// from lower offsets to higher offsets. - sequential, - /// The application expects to access the specified data in a random - /// order. - random, - /// The application expects to access the specified data in the near - /// future. - will-need, - /// The application expects that it will not access the specified data - /// in the near future. - dont-need, - /// The application expects to access the specified data once and then - /// not reuse it thereafter. - no-reuse, - } - - /// A 128-bit hash value, split into parts because wasm doesn't have a - /// 128-bit integer type. - record metadata-hash-value { - /// 64 bits of a 128-bit hash value. - lower: u64, - /// Another 64 bits of a 128-bit hash value. - upper: u64, - } - - /// A descriptor is a reference to a filesystem object, which may be a file, - /// directory, named pipe, special file, or other object on which filesystem - /// calls may be made. - resource descriptor { - /// Return a stream for reading from a file, if available. - /// - /// May fail with an error-code describing why the file cannot be read. - /// - /// Multiple read, write, and append streams may be active on the same open - /// file and they do not interfere with each other. - /// - /// Note: This allows using `read-stream`, which is similar to `read` in POSIX. - read-via-stream: func( - /// The offset within the file at which to start reading. - offset: filesize, - ) -> result; - - /// Return a stream for writing to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be written. - /// - /// Note: This allows using `write-stream`, which is similar to `write` in - /// POSIX. - write-via-stream: func( - /// The offset within the file at which to start writing. - offset: filesize, - ) -> result; - - /// Return a stream for appending to a file, if available. - /// - /// May fail with an error-code describing why the file cannot be appended. - /// - /// Note: This allows using `write-stream`, which is similar to `write` with - /// `O_APPEND` in in POSIX. - append-via-stream: func() -> result; - - /// Provide file advisory information on a descriptor. - /// - /// This is similar to `posix_fadvise` in POSIX. - advise: func( - /// The offset within the file to which the advisory applies. - offset: filesize, - /// The length of the region to which the advisory applies. - length: filesize, - /// The advice. - advice: advice - ) -> result<_, error-code>; - - /// Synchronize the data of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fdatasync` in POSIX. - sync-data: func() -> result<_, error-code>; - - /// Get flags associated with a descriptor. - /// - /// Note: This returns similar flags to `fcntl(fd, F_GETFL)` in POSIX. - /// - /// Note: This returns the value that was the `fs_flags` value returned - /// from `fdstat_get` in earlier versions of WASI. - get-flags: func() -> result; - - /// Get the dynamic type of a descriptor. - /// - /// Note: This returns the same value as the `type` field of the `fd-stat` - /// returned by `stat`, `stat-at` and similar. - /// - /// Note: This returns similar flags to the `st_mode & S_IFMT` value provided - /// by `fstat` in POSIX. - /// - /// Note: This returns the value that was the `fs_filetype` value returned - /// from `fdstat_get` in earlier versions of WASI. - get-type: func() -> result; - - /// Adjust the size of an open file. If this increases the file's size, the - /// extra bytes are filled with zeros. - /// - /// Note: This was called `fd_filestat_set_size` in earlier versions of WASI. - set-size: func(size: filesize) -> result<_, error-code>; - - /// Adjust the timestamps of an open file or directory. - /// - /// Note: This is similar to `futimens` in POSIX. - /// - /// Note: This was called `fd_filestat_set_times` in earlier versions of WASI. - set-times: func( - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code>; - - /// Read from a descriptor, without using and updating the descriptor's offset. - /// - /// This function returns a list of bytes containing the data that was - /// read, along with a bool which, when true, indicates that the end of the - /// file was reached. The returned list will contain up to `length` bytes; it - /// may return fewer than requested, if the end of the file is reached or - /// if the I/O operation is interrupted. - /// - /// In the future, this may change to return a `stream`. - /// - /// Note: This is similar to `pread` in POSIX. - read: func( - /// The maximum number of bytes to read. - length: filesize, - /// The offset within the file at which to read. - offset: filesize, - ) -> result, bool>, error-code>; - - /// Write to a descriptor, without using and updating the descriptor's offset. - /// - /// It is valid to write past the end of a file; the file is extended to the - /// extent of the write, with bytes between the previous end and the start of - /// the write set to zero. - /// - /// In the future, this may change to take a `stream`. - /// - /// Note: This is similar to `pwrite` in POSIX. - write: func( - /// Data to write - buffer: list, - /// The offset within the file at which to write. - offset: filesize, - ) -> result; - - /// Read directory entries from a directory. - /// - /// On filesystems where directories contain entries referring to themselves - /// and their parents, often named `.` and `..` respectively, these entries - /// are omitted. - /// - /// This always returns a new stream which starts at the beginning of the - /// directory. Multiple streams may be active on the same directory, and they - /// do not interfere with each other. - read-directory: func() -> result; - - /// Synchronize the data and metadata of a file to disk. - /// - /// This function succeeds with no effect if the file descriptor is not - /// opened for writing. - /// - /// Note: This is similar to `fsync` in POSIX. - sync: func() -> result<_, error-code>; - - /// Create a directory. - /// - /// Note: This is similar to `mkdirat` in POSIX. - create-directory-at: func( - /// The relative path at which to create the directory. - path: string, - ) -> result<_, error-code>; - - /// Return the attributes of an open file or directory. - /// - /// Note: This is similar to `fstat` in POSIX, except that it does not return - /// device and inode information. For testing whether two descriptors refer to - /// the same underlying filesystem object, use `is-same-object`. To obtain - /// additional data that can be used do determine whether a file has been - /// modified, use `metadata-hash`. - /// - /// Note: This was called `fd_filestat_get` in earlier versions of WASI. - stat: func() -> result; - - /// Return the attributes of a file or directory. - /// - /// Note: This is similar to `fstatat` in POSIX, except that it does not - /// return device and inode information. See the `stat` description for a - /// discussion of alternatives. - /// - /// Note: This was called `path_filestat_get` in earlier versions of WASI. - stat-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result; - - /// Adjust the timestamps of a file or directory. - /// - /// Note: This is similar to `utimensat` in POSIX. - /// - /// Note: This was called `path_filestat_set_times` in earlier versions of - /// WASI. - set-times-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to operate on. - path: string, - /// The desired values of the data access timestamp. - data-access-timestamp: new-timestamp, - /// The desired values of the data modification timestamp. - data-modification-timestamp: new-timestamp, - ) -> result<_, error-code>; - - /// Create a hard link. - /// - /// Note: This is similar to `linkat` in POSIX. - link-at: func( - /// Flags determining the method of how the path is resolved. - old-path-flags: path-flags, - /// The relative source path from which to link. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: borrow, - /// The relative destination path at which to create the hard link. - new-path: string, - ) -> result<_, error-code>; - - /// Open a file or directory. - /// - /// The returned descriptor is not guaranteed to be the lowest-numbered - /// descriptor not currently open/ it is randomized to prevent applications - /// from depending on making assumptions about indexes, since this is - /// error-prone in multi-threaded contexts. The returned descriptor is - /// guaranteed to be less than 2**31. - /// - /// If `flags` contains `descriptor-flags::mutate-directory`, and the base - /// descriptor doesn't have `descriptor-flags::mutate-directory` set, - /// `open-at` fails with `error-code::read-only`. - /// - /// If `flags` contains `write` or `mutate-directory`, or `open-flags` - /// contains `truncate` or `create`, and the base descriptor doesn't have - /// `descriptor-flags::mutate-directory` set, `open-at` fails with - /// `error-code::read-only`. - /// - /// Note: This is similar to `openat` in POSIX. - open-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the object to open. - path: string, - /// The method by which to open the file. - open-flags: open-flags, - /// Flags to use for the resulting descriptor. - %flags: descriptor-flags, - ) -> result; - - /// Read the contents of a symbolic link. - /// - /// If the contents contain an absolute or rooted path in the underlying - /// filesystem, this function fails with `error-code::not-permitted`. - /// - /// Note: This is similar to `readlinkat` in POSIX. - readlink-at: func( - /// The relative path of the symbolic link from which to read. - path: string, - ) -> result; - - /// Remove a directory. - /// - /// Return `error-code::not-empty` if the directory is not empty. - /// - /// Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX. - remove-directory-at: func( - /// The relative path to a directory to remove. - path: string, - ) -> result<_, error-code>; - - /// Rename a filesystem object. - /// - /// Note: This is similar to `renameat` in POSIX. - rename-at: func( - /// The relative source path of the file or directory to rename. - old-path: string, - /// The base directory for `new-path`. - new-descriptor: borrow, - /// The relative destination path to which to rename the file or directory. - new-path: string, - ) -> result<_, error-code>; - - /// Create a symbolic link (also known as a "symlink"). - /// - /// If `old-path` starts with `/`, the function fails with - /// `error-code::not-permitted`. - /// - /// Note: This is similar to `symlinkat` in POSIX. - symlink-at: func( - /// The contents of the symbolic link. - old-path: string, - /// The relative destination path at which to create the symbolic link. - new-path: string, - ) -> result<_, error-code>; - - /// Unlink a filesystem object that is not a directory. - /// - /// Return `error-code::is-directory` if the path refers to a directory. - /// Note: This is similar to `unlinkat(fd, path, 0)` in POSIX. - unlink-file-at: func( - /// The relative path to a file to unlink. - path: string, - ) -> result<_, error-code>; - - /// Test whether two descriptors refer to the same filesystem object. - /// - /// In POSIX, this corresponds to testing whether the two descriptors have the - /// same device (`st_dev`) and inode (`st_ino` or `d_ino`) numbers. - /// wasi-filesystem does not expose device and inode numbers, so this function - /// may be used instead. - is-same-object: func(other: borrow) -> bool; - - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a descriptor. - /// - /// This returns a hash of the last-modification timestamp and file size, and - /// may also include the inode number, device number, birth timestamp, and - /// other metadata fields that may change when the file is modified or - /// replaced. It may also include a secret value chosen by the - /// implementation and not otherwise exposed. - /// - /// Implementations are encourated to provide the following properties: - /// - /// - If the file is not modified or replaced, the computed hash value should - /// usually not change. - /// - If the object is modified or replaced, the computed hash value should - /// usually change. - /// - The inputs to the hash should not be easily computable from the - /// computed hash. - /// - /// However, none of these is required. - metadata-hash: func() -> result; - - /// Return a hash of the metadata associated with a filesystem object referred - /// to by a directory descriptor and a relative path. - /// - /// This performs the same hash computation as `metadata-hash`. - metadata-hash-at: func( - /// Flags determining the method of how the path is resolved. - path-flags: path-flags, - /// The relative path of the file or directory to inspect. - path: string, - ) -> result; - } - - /// A stream of directory entries. - resource directory-entry-stream { - /// Read a single directory entry from a `directory-entry-stream`. - read-directory-entry: func() -> result, error-code>; - } - - /// Attempts to extract a filesystem-related `error-code` from the stream - /// `error` provided. - /// - /// Stream operations which return `stream-error::last-operation-failed` - /// have a payload with more information about the operation that failed. - /// This payload can be passed through to this function to see if there's - /// filesystem-related information about the error to return. - /// - /// Note that this function is fallible because not all stream-related - /// errors are filesystem-related errors. - filesystem-error-code: func(err: borrow) -> option; -} diff --git a/tests/program/wit/deps/filesystem/world.wit b/tests/program/wit/deps/filesystem/world.wit deleted file mode 100644 index 663f579..0000000 --- a/tests/program/wit/deps/filesystem/world.wit +++ /dev/null @@ -1,6 +0,0 @@ -package wasi:filesystem@0.2.0; - -world imports { - import types; - import preopens; -} diff --git a/tests/program/wit/deps/io/error.wit b/tests/program/wit/deps/io/error.wit deleted file mode 100644 index 22e5b64..0000000 --- a/tests/program/wit/deps/io/error.wit +++ /dev/null @@ -1,34 +0,0 @@ -package wasi:io@0.2.0; - - -interface error { - /// A resource which represents some error information. - /// - /// The only method provided by this resource is `to-debug-string`, - /// which provides some human-readable information about the error. - /// - /// In the `wasi:io` package, this resource is returned through the - /// `wasi:io/streams/stream-error` type. - /// - /// To provide more specific error information, other interfaces may - /// provide functions to further "downcast" this error into more specific - /// error information. For example, `error`s returned in streams derived - /// from filesystem types to be described using the filesystem's own - /// error-code type, using the function - /// `wasi:filesystem/types/filesystem-error-code`, which takes a parameter - /// `borrow` and returns - /// `option`. - /// - /// The set of functions which can "downcast" an `error` into a more - /// concrete type is open. - resource error { - /// Returns a string that is suitable to assist humans in debugging - /// this error. - /// - /// WARNING: The returned string should not be consumed mechanically! - /// It may change across platforms, hosts, or other implementation - /// details. Parsing this string is a major platform-compatibility - /// hazard. - to-debug-string: func() -> string; - } -} diff --git a/tests/program/wit/deps/io/poll.wit b/tests/program/wit/deps/io/poll.wit deleted file mode 100644 index ddc67f8..0000000 --- a/tests/program/wit/deps/io/poll.wit +++ /dev/null @@ -1,41 +0,0 @@ -package wasi:io@0.2.0; - -/// A poll API intended to let users wait for I/O events on multiple handles -/// at once. -interface poll { - /// `pollable` represents a single I/O event which may be ready, or not. - resource pollable { - - /// Return the readiness of a pollable. This function never blocks. - /// - /// Returns `true` when the pollable is ready, and `false` otherwise. - ready: func() -> bool; - - /// `block` returns immediately if the pollable is ready, and otherwise - /// blocks until ready. - /// - /// This function is equivalent to calling `poll.poll` on a list - /// containing only this pollable. - block: func(); - } - - /// Poll for completion on a set of pollables. - /// - /// This function takes a list of pollables, which identify I/O sources of - /// interest, and waits until one or more of the events is ready for I/O. - /// - /// The result `list` contains one or more indices of handles in the - /// argument list that is ready for I/O. - /// - /// If the list contains more elements than can be indexed with a `u32` - /// value, this function traps. - /// - /// A timeout can be implemented by adding a pollable from the - /// wasi-clocks API to the list. - /// - /// This function does not return a `result`; polling in itself does not - /// do any I/O so it doesn't fail. If any of the I/O sources identified by - /// the pollables has an error, it is indicated by marking the source as - /// being reaedy for I/O. - poll: func(in: list>) -> list; -} diff --git a/tests/program/wit/deps/io/streams.wit b/tests/program/wit/deps/io/streams.wit deleted file mode 100644 index 6d2f871..0000000 --- a/tests/program/wit/deps/io/streams.wit +++ /dev/null @@ -1,262 +0,0 @@ -package wasi:io@0.2.0; - -/// WASI I/O is an I/O abstraction API which is currently focused on providing -/// stream types. -/// -/// In the future, the component model is expected to add built-in stream types; -/// when it does, they are expected to subsume this API. -interface streams { - use error.{error}; - use poll.{pollable}; - - /// An error for input-stream and output-stream operations. - variant stream-error { - /// The last operation (a write or flush) failed before completion. - /// - /// More information is available in the `error` payload. - last-operation-failed(error), - /// The stream is closed: no more input will be accepted by the - /// stream. A closed output-stream will return this error on all - /// future operations. - closed - } - - /// An input bytestream. - /// - /// `input-stream`s are *non-blocking* to the extent practical on underlying - /// platforms. I/O operations always return promptly; if fewer bytes are - /// promptly available than requested, they return the number of bytes promptly - /// available, which could even be zero. To wait for data to be available, - /// use the `subscribe` function to obtain a `pollable` which can be polled - /// for using `wasi:io/poll`. - resource input-stream { - /// Perform a non-blocking read from the stream. - /// - /// When the source of a `read` is binary data, the bytes from the source - /// are returned verbatim. When the source of a `read` is known to the - /// implementation to be text, bytes containing the UTF-8 encoding of the - /// text are returned. - /// - /// This function returns a list of bytes containing the read data, - /// when successful. The returned list will contain up to `len` bytes; - /// it may return fewer than requested, but not more. The list is - /// empty when no bytes are available for reading at this time. The - /// pollable given by `subscribe` will be ready when more bytes are - /// available. - /// - /// This function fails with a `stream-error` when the operation - /// encounters an error, giving `last-operation-failed`, or when the - /// stream is closed, giving `closed`. - /// - /// When the caller gives a `len` of 0, it represents a request to - /// read 0 bytes. If the stream is still open, this call should - /// succeed and return an empty list, or otherwise fail with `closed`. - /// - /// The `len` parameter is a `u64`, which could represent a list of u8 which - /// is not possible to allocate in wasm32, or not desirable to allocate as - /// as a return value by the callee. The callee may return a list of bytes - /// less than `len` in size while more bytes are available for reading. - read: func( - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-error>; - - /// Read bytes from a stream, after blocking until at least one byte can - /// be read. Except for blocking, behavior is identical to `read`. - blocking-read: func( - /// The maximum number of bytes to read - len: u64 - ) -> result, stream-error>; - - /// Skip bytes from a stream. Returns number of bytes skipped. - /// - /// Behaves identical to `read`, except instead of returning a list - /// of bytes, returns the number of bytes consumed from the stream. - skip: func( - /// The maximum number of bytes to skip. - len: u64, - ) -> result; - - /// Skip bytes from a stream, after blocking until at least one byte - /// can be skipped. Except for blocking behavior, identical to `skip`. - blocking-skip: func( - /// The maximum number of bytes to skip. - len: u64, - ) -> result; - - /// Create a `pollable` which will resolve once either the specified stream - /// has bytes available to read or the other end of the stream has been - /// closed. - /// The created `pollable` is a child resource of the `input-stream`. - /// Implementations may trap if the `input-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable; - } - - - /// An output bytestream. - /// - /// `output-stream`s are *non-blocking* to the extent practical on - /// underlying platforms. Except where specified otherwise, I/O operations also - /// always return promptly, after the number of bytes that can be written - /// promptly, which could even be zero. To wait for the stream to be ready to - /// accept data, the `subscribe` function to obtain a `pollable` which can be - /// polled for using `wasi:io/poll`. - resource output-stream { - /// Check readiness for writing. This function never blocks. - /// - /// Returns the number of bytes permitted for the next call to `write`, - /// or an error. Calling `write` with more bytes than this function has - /// permitted will trap. - /// - /// When this function returns 0 bytes, the `subscribe` pollable will - /// become ready when this function will report at least 1 byte, or an - /// error. - check-write: func() -> result; - - /// Perform a write. This function never blocks. - /// - /// When the destination of a `write` is binary data, the bytes from - /// `contents` are written verbatim. When the destination of a `write` is - /// known to the implementation to be text, the bytes of `contents` are - /// transcoded from UTF-8 into the encoding of the destination and then - /// written. - /// - /// Precondition: check-write gave permit of Ok(n) and contents has a - /// length of less than or equal to n. Otherwise, this function will trap. - /// - /// returns Err(closed) without writing if the stream has closed since - /// the last call to check-write provided a permit. - write: func( - contents: list - ) -> result<_, stream-error>; - - /// Perform a write of up to 4096 bytes, and then flush the stream. Block - /// until all of these operations are complete, or an error occurs. - /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write`, and `flush`, and is implemented with the - /// following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while !contents.is_empty() { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, contents.len()); - /// let (chunk, rest) = contents.split_at(len); - /// this.write(chunk ); // eliding error handling - /// contents = rest; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` - blocking-write-and-flush: func( - contents: list - ) -> result<_, stream-error>; - - /// Request to flush buffered output. This function never blocks. - /// - /// This tells the output-stream that the caller intends any buffered - /// output to be flushed. the output which is expected to be flushed - /// is all that has been passed to `write` prior to this call. - /// - /// Upon calling this function, the `output-stream` will not accept any - /// writes (`check-write` will return `ok(0)`) until the flush has - /// completed. The `subscribe` pollable will become ready when the - /// flush has completed and the stream can accept more writes. - flush: func() -> result<_, stream-error>; - - /// Request to flush buffered output, and block until flush completes - /// and stream is ready for writing again. - blocking-flush: func() -> result<_, stream-error>; - - /// Create a `pollable` which will resolve once the output-stream - /// is ready for more writing, or an error has occured. When this - /// pollable is ready, `check-write` will return `ok(n)` with n>0, or an - /// error. - /// - /// If the stream is closed, this pollable is always ready immediately. - /// - /// The created `pollable` is a child resource of the `output-stream`. - /// Implementations may trap if the `output-stream` is dropped before - /// all derived `pollable`s created with this function are dropped. - subscribe: func() -> pollable; - - /// Write zeroes to a stream. - /// - /// This should be used precisely like `write` with the exact same - /// preconditions (must use check-write first), but instead of - /// passing a list of bytes, you simply pass the number of zero-bytes - /// that should be written. - write-zeroes: func( - /// The number of zero-bytes to write - len: u64 - ) -> result<_, stream-error>; - - /// Perform a write of up to 4096 zeroes, and then flush the stream. - /// Block until all of these operations are complete, or an error - /// occurs. - /// - /// This is a convenience wrapper around the use of `check-write`, - /// `subscribe`, `write-zeroes`, and `flush`, and is implemented with - /// the following pseudo-code: - /// - /// ```text - /// let pollable = this.subscribe(); - /// while num_zeroes != 0 { - /// // Wait for the stream to become writable - /// pollable.block(); - /// let Ok(n) = this.check-write(); // eliding error handling - /// let len = min(n, num_zeroes); - /// this.write-zeroes(len); // eliding error handling - /// num_zeroes -= len; - /// } - /// this.flush(); - /// // Wait for completion of `flush` - /// pollable.block(); - /// // Check for any errors that arose during `flush` - /// let _ = this.check-write(); // eliding error handling - /// ``` - blocking-write-zeroes-and-flush: func( - /// The number of zero-bytes to write - len: u64 - ) -> result<_, stream-error>; - - /// Read from one stream and write to another. - /// - /// The behavior of splice is equivelant to: - /// 1. calling `check-write` on the `output-stream` - /// 2. calling `read` on the `input-stream` with the smaller of the - /// `check-write` permitted length and the `len` provided to `splice` - /// 3. calling `write` on the `output-stream` with that read data. - /// - /// Any error reported by the call to `check-write`, `read`, or - /// `write` ends the splice and reports that error. - /// - /// This function returns the number of bytes transferred; it may be less - /// than `len`. - splice: func( - /// The stream to read from - src: borrow, - /// The number of bytes to splice - len: u64, - ) -> result; - - /// Read from one stream and write to another, with blocking. - /// - /// This is similar to `splice`, except that it blocks until the - /// `output-stream` is ready for writing, and the `input-stream` - /// is ready for reading, before performing the `splice`. - blocking-splice: func( - /// The stream to read from - src: borrow, - /// The number of bytes to splice - len: u64, - ) -> result; - } -} diff --git a/tests/program/wit/deps/io/world.wit b/tests/program/wit/deps/io/world.wit deleted file mode 100644 index 5f0b43f..0000000 --- a/tests/program/wit/deps/io/world.wit +++ /dev/null @@ -1,6 +0,0 @@ -package wasi:io@0.2.0; - -world imports { - import streams; - import poll; -} diff --git a/tests/program/wit/deps/random/insecure-seed.wit b/tests/program/wit/deps/random/insecure-seed.wit deleted file mode 100644 index 47210ac..0000000 --- a/tests/program/wit/deps/random/insecure-seed.wit +++ /dev/null @@ -1,25 +0,0 @@ -package wasi:random@0.2.0; -/// The insecure-seed interface for seeding hash-map DoS resistance. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -interface insecure-seed { - /// Return a 128-bit value that may contain a pseudo-random value. - /// - /// The returned value is not required to be computed from a CSPRNG, and may - /// even be entirely deterministic. Host implementations are encouraged to - /// provide pseudo-random values to any program exposed to - /// attacker-controlled content, to enable DoS protection built into many - /// languages' hash-map implementations. - /// - /// This function is intended to only be called once, by a source language - /// to initialize Denial Of Service (DoS) protection in its hash-map - /// implementation. - /// - /// # Expected future evolution - /// - /// This will likely be changed to a value import, to prevent it from being - /// called multiple times and potentially used for purposes other than DoS - /// protection. - insecure-seed: func() -> tuple; -} diff --git a/tests/program/wit/deps/random/insecure.wit b/tests/program/wit/deps/random/insecure.wit deleted file mode 100644 index c58f4ee..0000000 --- a/tests/program/wit/deps/random/insecure.wit +++ /dev/null @@ -1,22 +0,0 @@ -package wasi:random@0.2.0; -/// The insecure interface for insecure pseudo-random numbers. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -interface insecure { - /// Return `len` insecure pseudo-random bytes. - /// - /// This function is not cryptographically secure. Do not use it for - /// anything related to security. - /// - /// There are no requirements on the values of the returned bytes, however - /// implementations are encouraged to return evenly distributed values with - /// a long period. - get-insecure-random-bytes: func(len: u64) -> list; - - /// Return an insecure pseudo-random `u64` value. - /// - /// This function returns the same type of pseudo-random data as - /// `get-insecure-random-bytes`, represented as a `u64`. - get-insecure-random-u64: func() -> u64; -} diff --git a/tests/program/wit/deps/random/random.wit b/tests/program/wit/deps/random/random.wit deleted file mode 100644 index 0c017f0..0000000 --- a/tests/program/wit/deps/random/random.wit +++ /dev/null @@ -1,26 +0,0 @@ -package wasi:random@0.2.0; -/// WASI Random is a random data API. -/// -/// It is intended to be portable at least between Unix-family platforms and -/// Windows. -interface random { - /// Return `len` cryptographically-secure random or pseudo-random bytes. - /// - /// This function must produce data at least as cryptographically secure and - /// fast as an adequately seeded cryptographically-secure pseudo-random - /// number generator (CSPRNG). It must not block, from the perspective of - /// the calling program, under any circumstances, including on the first - /// request and on requests for numbers of bytes. The returned data must - /// always be unpredictable. - /// - /// This function must always return fresh data. Deterministic environments - /// must omit this function, rather than implementing it with deterministic - /// data. - get-random-bytes: func(len: u64) -> list; - - /// Return a cryptographically-secure random or pseudo-random `u64` value. - /// - /// This function returns the same type of data as `get-random-bytes`, - /// represented as a `u64`. - get-random-u64: func() -> u64; -} diff --git a/tests/program/wit/deps/random/world.wit b/tests/program/wit/deps/random/world.wit deleted file mode 100644 index 3da3491..0000000 --- a/tests/program/wit/deps/random/world.wit +++ /dev/null @@ -1,7 +0,0 @@ -package wasi:random@0.2.0; - -world imports { - import random; - import insecure; - import insecure-seed; -} diff --git a/tests/program/wit/deps/sockets/instance-network.wit b/tests/program/wit/deps/sockets/instance-network.wit deleted file mode 100644 index e455d0f..0000000 --- a/tests/program/wit/deps/sockets/instance-network.wit +++ /dev/null @@ -1,9 +0,0 @@ - -/// This interface provides a value-export of the default network handle.. -interface instance-network { - use network.{network}; - - /// Get a handle to the default network. - instance-network: func() -> network; - -} diff --git a/tests/program/wit/deps/sockets/ip-name-lookup.wit b/tests/program/wit/deps/sockets/ip-name-lookup.wit deleted file mode 100644 index 8e639ec..0000000 --- a/tests/program/wit/deps/sockets/ip-name-lookup.wit +++ /dev/null @@ -1,51 +0,0 @@ - -interface ip-name-lookup { - use wasi:io/poll@0.2.0.{pollable}; - use network.{network, error-code, ip-address}; - - - /// Resolve an internet host name to a list of IP addresses. - /// - /// Unicode domain names are automatically converted to ASCII using IDNA encoding. - /// If the input is an IP address string, the address is parsed and returned - /// as-is without making any external requests. - /// - /// See the wasi-socket proposal README.md for a comparison with getaddrinfo. - /// - /// This function never blocks. It either immediately fails or immediately - /// returns successfully with a `resolve-address-stream` that can be used - /// to (asynchronously) fetch the results. - /// - /// # Typical errors - /// - `invalid-argument`: `name` is a syntactically invalid domain name or IP address. - /// - /// # References: - /// - - /// - - /// - - /// - - resolve-addresses: func(network: borrow, name: string) -> result; - - resource resolve-address-stream { - /// Returns the next address from the resolver. - /// - /// This function should be called multiple times. On each call, it will - /// return the next address in connection order preference. If all - /// addresses have been exhausted, this function returns `none`. - /// - /// This function never returns IPv4-mapped IPv6 addresses. - /// - /// # Typical errors - /// - `name-unresolvable`: Name does not exist or has no suitable associated IP addresses. (EAI_NONAME, EAI_NODATA, EAI_ADDRFAMILY) - /// - `temporary-resolver-failure`: A temporary failure in name resolution occurred. (EAI_AGAIN) - /// - `permanent-resolver-failure`: A permanent failure in name resolution occurred. (EAI_FAIL) - /// - `would-block`: A result is not available yet. (EWOULDBLOCK, EAGAIN) - resolve-next-address: func() -> result, error-code>; - - /// Create a `pollable` which will resolve once the stream is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - } -} diff --git a/tests/program/wit/deps/sockets/network.wit b/tests/program/wit/deps/sockets/network.wit deleted file mode 100644 index 9cadf06..0000000 --- a/tests/program/wit/deps/sockets/network.wit +++ /dev/null @@ -1,145 +0,0 @@ - -interface network { - /// An opaque resource that represents access to (a subset of) the network. - /// This enables context-based security for networking. - /// There is no need for this to map 1:1 to a physical network interface. - resource network; - - /// Error codes. - /// - /// In theory, every API can return any error code. - /// In practice, API's typically only return the errors documented per API - /// combined with a couple of errors that are always possible: - /// - `unknown` - /// - `access-denied` - /// - `not-supported` - /// - `out-of-memory` - /// - `concurrency-conflict` - /// - /// See each individual API for what the POSIX equivalents are. They sometimes differ per API. - enum error-code { - /// Unknown error - unknown, - - /// Access denied. - /// - /// POSIX equivalent: EACCES, EPERM - access-denied, - - /// The operation is not supported. - /// - /// POSIX equivalent: EOPNOTSUPP - not-supported, - - /// One of the arguments is invalid. - /// - /// POSIX equivalent: EINVAL - invalid-argument, - - /// Not enough memory to complete the operation. - /// - /// POSIX equivalent: ENOMEM, ENOBUFS, EAI_MEMORY - out-of-memory, - - /// The operation timed out before it could finish completely. - timeout, - - /// This operation is incompatible with another asynchronous operation that is already in progress. - /// - /// POSIX equivalent: EALREADY - concurrency-conflict, - - /// Trying to finish an asynchronous operation that: - /// - has not been started yet, or: - /// - was already finished by a previous `finish-*` call. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - not-in-progress, - - /// The operation has been aborted because it could not be completed immediately. - /// - /// Note: this is scheduled to be removed when `future`s are natively supported. - would-block, - - - /// The operation is not valid in the socket's current state. - invalid-state, - - /// A new socket resource could not be created because of a system limit. - new-socket-limit, - - /// A bind operation failed because the provided address is not an address that the `network` can bind to. - address-not-bindable, - - /// A bind operation failed because the provided address is already in use or because there are no ephemeral ports available. - address-in-use, - - /// The remote address is not reachable - remote-unreachable, - - - /// The TCP connection was forcefully rejected - connection-refused, - - /// The TCP connection was reset. - connection-reset, - - /// A TCP connection was aborted. - connection-aborted, - - - /// The size of a datagram sent to a UDP socket exceeded the maximum - /// supported size. - datagram-too-large, - - - /// Name does not exist or has no suitable associated IP addresses. - name-unresolvable, - - /// A temporary failure in name resolution occurred. - temporary-resolver-failure, - - /// A permanent failure in name resolution occurred. - permanent-resolver-failure, - } - - enum ip-address-family { - /// Similar to `AF_INET` in POSIX. - ipv4, - - /// Similar to `AF_INET6` in POSIX. - ipv6, - } - - type ipv4-address = tuple; - type ipv6-address = tuple; - - variant ip-address { - ipv4(ipv4-address), - ipv6(ipv6-address), - } - - record ipv4-socket-address { - /// sin_port - port: u16, - /// sin_addr - address: ipv4-address, - } - - record ipv6-socket-address { - /// sin6_port - port: u16, - /// sin6_flowinfo - flow-info: u32, - /// sin6_addr - address: ipv6-address, - /// sin6_scope_id - scope-id: u32, - } - - variant ip-socket-address { - ipv4(ipv4-socket-address), - ipv6(ipv6-socket-address), - } - -} diff --git a/tests/program/wit/deps/sockets/tcp-create-socket.wit b/tests/program/wit/deps/sockets/tcp-create-socket.wit deleted file mode 100644 index c7ddf1f..0000000 --- a/tests/program/wit/deps/sockets/tcp-create-socket.wit +++ /dev/null @@ -1,27 +0,0 @@ - -interface tcp-create-socket { - use network.{network, error-code, ip-address-family}; - use tcp.{tcp-socket}; - - /// Create a new TCP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_STREAM, IPPROTO_TCP)` in POSIX. - /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind`/`connect` - /// is called, the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References - /// - - /// - - /// - - /// - - create-tcp-socket: func(address-family: ip-address-family) -> result; -} diff --git a/tests/program/wit/deps/sockets/tcp.wit b/tests/program/wit/deps/sockets/tcp.wit deleted file mode 100644 index 5902b9e..0000000 --- a/tests/program/wit/deps/sockets/tcp.wit +++ /dev/null @@ -1,353 +0,0 @@ - -interface tcp { - use wasi:io/streams@0.2.0.{input-stream, output-stream}; - use wasi:io/poll@0.2.0.{pollable}; - use wasi:clocks/monotonic-clock@0.2.0.{duration}; - use network.{network, error-code, ip-socket-address, ip-address-family}; - - enum shutdown-type { - /// Similar to `SHUT_RD` in POSIX. - receive, - - /// Similar to `SHUT_WR` in POSIX. - send, - - /// Similar to `SHUT_RDWR` in POSIX. - both, - } - - /// A TCP socket resource. - /// - /// The socket can be in one of the following states: - /// - `unbound` - /// - `bind-in-progress` - /// - `bound` (See note below) - /// - `listen-in-progress` - /// - `listening` - /// - `connect-in-progress` - /// - `connected` - /// - `closed` - /// See - /// for a more information. - /// - /// Note: Except where explicitly mentioned, whenever this documentation uses - /// the term "bound" without backticks it actually means: in the `bound` state *or higher*. - /// (i.e. `bound`, `listen-in-progress`, `listening`, `connect-in-progress` or `connected`) - /// - /// In addition to the general error codes documented on the - /// `network::error-code` type, TCP socket methods may always return - /// `error(invalid-state)` when in the `closed` state. - resource tcp-socket { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the TCP/UDP port is zero, the socket will be bound to a random free port. - /// - /// Bind can be attempted multiple times on the same socket, even with - /// different arguments on each iteration. But never concurrently and - /// only as long as the previous bind failed. Once a bind succeeds, the - /// binding can't be changed anymore. - /// - /// # Typical errors - /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) - /// - `invalid-argument`: `local-address` is not a unicast address. (EINVAL) - /// - `invalid-argument`: `local-address` is an IPv4-mapped IPv6 address. (EINVAL) - /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// When binding to a non-zero port, this bind operation shouldn't be affected by the TIME_WAIT - /// state of a recently closed socket on the same local address. In practice this means that the SO_REUSEADDR - /// socket option should be set implicitly on all platforms, except on Windows where this is the default behavior - /// and SO_REUSEADDR performs something different entirely. - /// - /// Unlike in POSIX, in WASI the bind operation is async. This enables - /// interactive WASI hosts to inject permission prompts. Runtimes that - /// don't want to make use of this ability can simply call the native - /// `bind` as part of either `start-bind` or `finish-bind`. - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; - finish-bind: func() -> result<_, error-code>; - - /// Connect to a remote endpoint. - /// - /// On success: - /// - the socket is transitioned into the `connection` state. - /// - a pair of streams is returned that can be used to read & write to the connection - /// - /// After a failed connection attempt, the socket will be in the `closed` - /// state and the only valid action left is to `drop` the socket. A single - /// socket can not be used to connect more than once. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: `remote-address` is not a unicast address. (EINVAL, ENETUNREACH on Linux, EAFNOSUPPORT on MacOS) - /// - `invalid-argument`: `remote-address` is an IPv4-mapped IPv6 address. (EINVAL, EADDRNOTAVAIL on Illumos) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EADDRNOTAVAIL on Windows) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EADDRNOTAVAIL on Windows) - /// - `invalid-argument`: The socket is already attached to a different network. The `network` passed to `connect` must be identical to the one passed to `bind`. - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN) - /// - `invalid-state`: The socket is already in the `listening` state. (EOPNOTSUPP, EINVAL on Windows) - /// - `timeout`: Connection timed out. (ETIMEDOUT) - /// - `connection-refused`: The connection was forcefully rejected. (ECONNREFUSED) - /// - `connection-reset`: The connection was reset. (ECONNRESET) - /// - `connection-aborted`: The connection was aborted. (ECONNABORTED) - /// - `remote-unreachable`: The remote address is not reachable. (EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `not-in-progress`: A connect operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// The POSIX equivalent of `start-connect` is the regular `connect` syscall. - /// Because all WASI sockets are non-blocking this is expected to return - /// EINPROGRESS, which should be translated to `ok()` in WASI. - /// - /// The POSIX equivalent of `finish-connect` is a `poll` for event `POLLOUT` - /// with a timeout of 0 on the socket descriptor. Followed by a check for - /// the `SO_ERROR` socket option, in case the poll signaled readiness. - /// - /// # References - /// - - /// - - /// - - /// - - start-connect: func(network: borrow, remote-address: ip-socket-address) -> result<_, error-code>; - finish-connect: func() -> result, error-code>; - - /// Start listening for new connections. - /// - /// Transitions the socket into the `listening` state. - /// - /// Unlike POSIX, the socket must already be explicitly bound. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. (EDESTADDRREQ) - /// - `invalid-state`: The socket is already in the `connected` state. (EISCONN, EINVAL on BSD) - /// - `invalid-state`: The socket is already in the `listening` state. - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE) - /// - `not-in-progress`: A listen operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// Unlike in POSIX, in WASI the listen operation is async. This enables - /// interactive WASI hosts to inject permission prompts. Runtimes that - /// don't want to make use of this ability can simply call the native - /// `listen` as part of either `start-listen` or `finish-listen`. - /// - /// # References - /// - - /// - - /// - - /// - - start-listen: func() -> result<_, error-code>; - finish-listen: func() -> result<_, error-code>; - - /// Accept a new client socket. - /// - /// The returned socket is bound and in the `connected` state. The following properties are inherited from the listener socket: - /// - `address-family` - /// - `keep-alive-enabled` - /// - `keep-alive-idle-time` - /// - `keep-alive-interval` - /// - `keep-alive-count` - /// - `hop-limit` - /// - `receive-buffer-size` - /// - `send-buffer-size` - /// - /// On success, this function returns the newly accepted client socket along with - /// a pair of streams that can be used to read & write to the connection. - /// - /// # Typical errors - /// - `invalid-state`: Socket is not in the `listening` state. (EINVAL) - /// - `would-block`: No pending connections at the moment. (EWOULDBLOCK, EAGAIN) - /// - `connection-aborted`: An incoming connection was pending, but was terminated by the client before this listener could accept it. (ECONNABORTED) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References - /// - - /// - - /// - - /// - - accept: func() -> result, error-code>; - - /// Get the bound local address. - /// - /// POSIX mentions: - /// > If the socket has not been bound to a local name, the value - /// > stored in the object pointed to by `address` is unspecified. - /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func() -> result; - - /// Get the remote address. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not connected to a remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func() -> result; - - /// Whether the socket is in the `listening` state. - /// - /// Equivalent to the SO_ACCEPTCONN socket option. - is-listening: func() -> bool; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family; - - /// Hints the desired listen queue size. Implementations are free to ignore this. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// - /// # Typical errors - /// - `not-supported`: (set) The platform does not support changing the backlog size after the initial listen. - /// - `invalid-argument`: (set) The provided value was 0. - /// - `invalid-state`: (set) The socket is in the `connect-in-progress` or `connected` state. - set-listen-backlog-size: func(value: u64) -> result<_, error-code>; - - /// Enables or disables keepalive. - /// - /// The keepalive behavior can be adjusted using: - /// - `keep-alive-idle-time` - /// - `keep-alive-interval` - /// - `keep-alive-count` - /// These properties can be configured while `keep-alive-enabled` is false, but only come into effect when `keep-alive-enabled` is true. - /// - /// Equivalent to the SO_KEEPALIVE socket option. - keep-alive-enabled: func() -> result; - set-keep-alive-enabled: func(value: bool) -> result<_, error-code>; - - /// Amount of time the connection has to be idle before TCP starts sending keepalive packets. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPIDLE socket option. (TCP_KEEPALIVE on MacOS) - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - keep-alive-idle-time: func() -> result; - set-keep-alive-idle-time: func(value: duration) -> result<_, error-code>; - - /// The time between keepalive packets. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPINTVL socket option. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - keep-alive-interval: func() -> result; - set-keep-alive-interval: func(value: duration) -> result<_, error-code>; - - /// The maximum amount of keepalive packets TCP should send before aborting the connection. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the TCP_KEEPCNT socket option. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - keep-alive-count: func() -> result; - set-keep-alive-count: func(value: u32) -> result<_, error-code>; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - hop-limit: func() -> result; - set-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - receive-buffer-size: func() -> result; - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - send-buffer-size: func() -> result; - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Create a `pollable` which can be used to poll for, or block on, - /// completion of any of the asynchronous operations of this socket. - /// - /// When `finish-bind`, `finish-listen`, `finish-connect` or `accept` - /// return `error(would-block)`, this pollable can be used to wait for - /// their success or failure, after which the method can be retried. - /// - /// The pollable is not limited to the async operation that happens to be - /// in progress at the time of calling `subscribe` (if any). Theoretically, - /// `subscribe` only has to be called once per socket and can then be - /// (re)used for the remainder of the socket's lifetime. - /// - /// See - /// for a more information. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - - /// Initiate a graceful shutdown. - /// - /// - `receive`: The socket is not expecting to receive any data from - /// the peer. The `input-stream` associated with this socket will be - /// closed. Any data still in the receive queue at time of calling - /// this method will be discarded. - /// - `send`: The socket has no more data to send to the peer. The `output-stream` - /// associated with this socket will be closed and a FIN packet will be sent. - /// - `both`: Same effect as `receive` & `send` combined. - /// - /// This function is idempotent. Shutting a down a direction more than once - /// has no effect and returns `ok`. - /// - /// The shutdown function does not close (drop) the socket. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not in the `connected` state. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - shutdown: func(shutdown-type: shutdown-type) -> result<_, error-code>; - } -} diff --git a/tests/program/wit/deps/sockets/udp-create-socket.wit b/tests/program/wit/deps/sockets/udp-create-socket.wit deleted file mode 100644 index 0482d1f..0000000 --- a/tests/program/wit/deps/sockets/udp-create-socket.wit +++ /dev/null @@ -1,27 +0,0 @@ - -interface udp-create-socket { - use network.{network, error-code, ip-address-family}; - use udp.{udp-socket}; - - /// Create a new UDP socket. - /// - /// Similar to `socket(AF_INET or AF_INET6, SOCK_DGRAM, IPPROTO_UDP)` in POSIX. - /// On IPv6 sockets, IPV6_V6ONLY is enabled by default and can't be configured otherwise. - /// - /// This function does not require a network capability handle. This is considered to be safe because - /// at time of creation, the socket is not bound to any `network` yet. Up to the moment `bind` is called, - /// the socket is effectively an in-memory configuration object, unable to communicate with the outside world. - /// - /// All sockets are non-blocking. Use the wasi-poll interface to block on asynchronous operations. - /// - /// # Typical errors - /// - `not-supported`: The specified `address-family` is not supported. (EAFNOSUPPORT) - /// - `new-socket-limit`: The new socket resource could not be created because of a system limit. (EMFILE, ENFILE) - /// - /// # References: - /// - - /// - - /// - - /// - - create-udp-socket: func(address-family: ip-address-family) -> result; -} diff --git a/tests/program/wit/deps/sockets/udp.wit b/tests/program/wit/deps/sockets/udp.wit deleted file mode 100644 index d987a0a..0000000 --- a/tests/program/wit/deps/sockets/udp.wit +++ /dev/null @@ -1,266 +0,0 @@ - -interface udp { - use wasi:io/poll@0.2.0.{pollable}; - use network.{network, error-code, ip-socket-address, ip-address-family}; - - /// A received datagram. - record incoming-datagram { - /// The payload. - /// - /// Theoretical max size: ~64 KiB. In practice, typically less than 1500 bytes. - data: list, - - /// The source address. - /// - /// This field is guaranteed to match the remote address the stream was initialized with, if any. - /// - /// Equivalent to the `src_addr` out parameter of `recvfrom`. - remote-address: ip-socket-address, - } - - /// A datagram to be sent out. - record outgoing-datagram { - /// The payload. - data: list, - - /// The destination address. - /// - /// The requirements on this field depend on how the stream was initialized: - /// - with a remote address: this field must be None or match the stream's remote address exactly. - /// - without a remote address: this field is required. - /// - /// If this value is None, the send operation is equivalent to `send` in POSIX. Otherwise it is equivalent to `sendto`. - remote-address: option, - } - - - - /// A UDP socket handle. - resource udp-socket { - /// Bind the socket to a specific network on the provided IP address and port. - /// - /// If the IP address is zero (`0.0.0.0` in IPv4, `::` in IPv6), it is left to the implementation to decide which - /// network interface(s) to bind to. - /// If the port is zero, the socket will be bound to a random free port. - /// - /// # Typical errors - /// - `invalid-argument`: The `local-address` has the wrong address family. (EAFNOSUPPORT, EFAULT on Windows) - /// - `invalid-state`: The socket is already bound. (EINVAL) - /// - `address-in-use`: No ephemeral ports available. (EADDRINUSE, ENOBUFS on Windows) - /// - `address-in-use`: Address is already in use. (EADDRINUSE) - /// - `address-not-bindable`: `local-address` is not an address that the `network` can bind to. (EADDRNOTAVAIL) - /// - `not-in-progress`: A `bind` operation is not in progress. - /// - `would-block`: Can't finish the operation, it is still in progress. (EWOULDBLOCK, EAGAIN) - /// - /// # Implementors note - /// Unlike in POSIX, in WASI the bind operation is async. This enables - /// interactive WASI hosts to inject permission prompts. Runtimes that - /// don't want to make use of this ability can simply call the native - /// `bind` as part of either `start-bind` or `finish-bind`. - /// - /// # References - /// - - /// - - /// - - /// - - start-bind: func(network: borrow, local-address: ip-socket-address) -> result<_, error-code>; - finish-bind: func() -> result<_, error-code>; - - /// Set up inbound & outbound communication channels, optionally to a specific peer. - /// - /// This function only changes the local socket configuration and does not generate any network traffic. - /// On success, the `remote-address` of the socket is updated. The `local-address` may be updated as well, - /// based on the best network path to `remote-address`. - /// - /// When a `remote-address` is provided, the returned streams are limited to communicating with that specific peer: - /// - `send` can only be used to send to this destination. - /// - `receive` will only return datagrams sent from the provided `remote-address`. - /// - /// This method may be called multiple times on the same socket to change its association, but - /// only the most recently returned pair of streams will be operational. Implementations may trap if - /// the streams returned by a previous invocation haven't been dropped yet before calling `stream` again. - /// - /// The POSIX equivalent in pseudo-code is: - /// ```text - /// if (was previously connected) { - /// connect(s, AF_UNSPEC) - /// } - /// if (remote_address is Some) { - /// connect(s, remote_address) - /// } - /// ``` - /// - /// Unlike in POSIX, the socket must already be explicitly bound. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-state`: The socket is not bound. - /// - `address-in-use`: Tried to perform an implicit bind, but there were no ephemeral ports available. (EADDRINUSE, EADDRNOTAVAIL on Linux, EAGAIN on BSD) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - /// # References - /// - - /// - - /// - - /// - - %stream: func(remote-address: option) -> result, error-code>; - - /// Get the current bound address. - /// - /// POSIX mentions: - /// > If the socket has not been bound to a local name, the value - /// > stored in the object pointed to by `address` is unspecified. - /// - /// WASI is stricter and requires `local-address` to return `invalid-state` when the socket hasn't been bound yet. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not bound to any local address. - /// - /// # References - /// - - /// - - /// - - /// - - local-address: func() -> result; - - /// Get the address the socket is currently streaming to. - /// - /// # Typical errors - /// - `invalid-state`: The socket is not streaming to a specific remote address. (ENOTCONN) - /// - /// # References - /// - - /// - - /// - - /// - - remote-address: func() -> result; - - /// Whether this is a IPv4 or IPv6 socket. - /// - /// Equivalent to the SO_DOMAIN socket option. - address-family: func() -> ip-address-family; - - /// Equivalent to the IP_TTL & IPV6_UNICAST_HOPS socket options. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The TTL value must be 1 or higher. - unicast-hop-limit: func() -> result; - set-unicast-hop-limit: func(value: u8) -> result<_, error-code>; - - /// The kernel buffer space reserved for sends/receives on this socket. - /// - /// If the provided value is 0, an `invalid-argument` error is returned. - /// Any other value will never cause an error, but it might be silently clamped and/or rounded. - /// I.e. after setting a value, reading the same setting back may return a different value. - /// - /// Equivalent to the SO_RCVBUF and SO_SNDBUF socket options. - /// - /// # Typical errors - /// - `invalid-argument`: (set) The provided value was 0. - receive-buffer-size: func() -> result; - set-receive-buffer-size: func(value: u64) -> result<_, error-code>; - send-buffer-size: func() -> result; - set-send-buffer-size: func(value: u64) -> result<_, error-code>; - - /// Create a `pollable` which will resolve once the socket is ready for I/O. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - } - - resource incoming-datagram-stream { - /// Receive messages on the socket. - /// - /// This function attempts to receive up to `max-results` datagrams on the socket without blocking. - /// The returned list may contain fewer elements than requested, but never more. - /// - /// This function returns successfully with an empty list when either: - /// - `max-results` is 0, or: - /// - `max-results` is greater than 0, but no results are immediately available. - /// This function never returns `error(would-block)`. - /// - /// # Typical errors - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - receive: func(max-results: u64) -> result, error-code>; - - /// Create a `pollable` which will resolve once the stream is ready to receive again. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - } - - resource outgoing-datagram-stream { - /// Check readiness for sending. This function never blocks. - /// - /// Returns the number of datagrams permitted for the next call to `send`, - /// or an error. Calling `send` with more datagrams than this function has - /// permitted will trap. - /// - /// When this function returns ok(0), the `subscribe` pollable will - /// become ready when this function will report at least ok(1), or an - /// error. - /// - /// Never returns `would-block`. - check-send: func() -> result; - - /// Send messages on the socket. - /// - /// This function attempts to send all provided `datagrams` on the socket without blocking and - /// returns how many messages were actually sent (or queued for sending). This function never - /// returns `error(would-block)`. If none of the datagrams were able to be sent, `ok(0)` is returned. - /// - /// This function semantically behaves the same as iterating the `datagrams` list and sequentially - /// sending each individual datagram until either the end of the list has been reached or the first error occurred. - /// If at least one datagram has been sent successfully, this function never returns an error. - /// - /// If the input list is empty, the function returns `ok(0)`. - /// - /// Each call to `send` must be permitted by a preceding `check-send`. Implementations must trap if - /// either `check-send` was not called or `datagrams` contains more items than `check-send` permitted. - /// - /// # Typical errors - /// - `invalid-argument`: The `remote-address` has the wrong address family. (EAFNOSUPPORT) - /// - `invalid-argument`: The IP address in `remote-address` is set to INADDR_ANY (`0.0.0.0` / `::`). (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The port in `remote-address` is set to 0. (EDESTADDRREQ, EADDRNOTAVAIL) - /// - `invalid-argument`: The socket is in "connected" mode and `remote-address` is `some` value that does not match the address passed to `stream`. (EISCONN) - /// - `invalid-argument`: The socket is not "connected" and no value for `remote-address` was provided. (EDESTADDRREQ) - /// - `remote-unreachable`: The remote address is not reachable. (ECONNRESET, ENETRESET on Windows, EHOSTUNREACH, EHOSTDOWN, ENETUNREACH, ENETDOWN, ENONET) - /// - `connection-refused`: The connection was refused. (ECONNREFUSED) - /// - `datagram-too-large`: The datagram is too large. (EMSGSIZE) - /// - /// # References - /// - - /// - - /// - - /// - - /// - - /// - - /// - - /// - - send: func(datagrams: list) -> result; - - /// Create a `pollable` which will resolve once the stream is ready to send again. - /// - /// Note: this function is here for WASI Preview2 only. - /// It's planned to be removed when `future` is natively supported in Preview3. - subscribe: func() -> pollable; - } -} diff --git a/tests/program/wit/deps/sockets/world.wit b/tests/program/wit/deps/sockets/world.wit deleted file mode 100644 index f8bb92a..0000000 --- a/tests/program/wit/deps/sockets/world.wit +++ /dev/null @@ -1,11 +0,0 @@ -package wasi:sockets@0.2.0; - -world imports { - import instance-network; - import network; - import udp; - import udp-create-socket; - import tcp; - import tcp-create-socket; - import ip-name-lookup; -} diff --git a/tests/program/wit/world.wit b/tests/program/wit/world.wit deleted file mode 100644 index 24ac84d..0000000 --- a/tests/program/wit/world.wit +++ /dev/null @@ -1,5 +0,0 @@ -package iawia002:wasi-http-client-test-program; - -world http-client { - include wasi:cli/command@0.2.0; -}