From 29d5f2210339aa487073a3372876c0a498e46379 Mon Sep 17 00:00:00 2001 From: Jeron Aldaron Lau Date: Fri, 2 Feb 2024 15:48:02 -0600 Subject: [PATCH] Support WASI (#84) --- CHANGELOG.md | 1 + Cargo.toml | 3 ++ README.md | 2 +- WASM.md | 19 +++++------- src/os.rs | 4 +-- src/os/wasi.rs | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 src/os/wasi.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index d286f2b..6bb15d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog], and this project adheres to ### Added + - WASI support - Fallible functions - `whoami::fallible::devicename()` - `whoami::fallible::devicename_os()` diff --git a/Cargo.toml b/Cargo.toml index 21b9a91..87082b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,9 @@ optional = true version = "0.2" optional = true +[target.'cfg(all(target_arch = "wasm32", target_os = "wasi"))'.dependencies.wasite] +version = "0.1" + [features] default = ["web"] # Enabling this feature indicates that the wasm32-unknown-unknown target should diff --git a/README.md b/README.md index d436031..5340904 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ WhoAmI targets all platforms that can run Rust, including: - [Web Assembly](https://github.com/ardaku/whoami/blob/stable/WASM.md) - Mock implementation - Web Browser - DOM - - WASI (Wasite/Quantii, others) **mock implementation, full implementation planned later** + - WASI (Wasite, others) **may partially or fully work - but untested** - Daku (Ardaku/Quantii, others) **mock implementation, full implementation planned later** - Illumos variants (SmartOS, OmniOS, others) **may partially or fully work - but untested** - Android **may partially or fully work - but untested, planned later** diff --git a/WASM.md b/WASM.md index 1cd9995..66f5b02 100644 --- a/WASM.md +++ b/WASM.md @@ -12,7 +12,6 @@ WhoAmI links to web-sys and defaults values to browser information: - `platform()`: Host operating system by view of browser (Example: "Linux") - `distro()`: Host distro by view of browser (Example "Unknown Linux") - `desktop_env()`: "Web Browser" - - `arch()`: "wasm32" ## Mock If you compile WhoAmI with `default-features = false`, WhoAmI will not bind to @@ -26,22 +25,20 @@ web-sys, and will instead return these mock values: - `platform()`: "Unknown" - `distro()`: "Emulated" - `desktop_env()`: "Unknown WebAssembly" - - `arch()`: "wasm32" ## Wasi (Wasite) Building WhoAmI targeting Wasi will assume the [wasite](https://ardaku.org/wasite/env_vars.html) environment variables are set, as Wasi alone does not currently support the functionality WhoAmI requires. - - `realname()`: `$USER` - - `username()`: `$USER` - - `lang()`: `$LANGS` - - `devicename()`: `$NAME` - - `hostname()`: `$HOSTNAME` - - `platform()`: "Wasite" - - `distro()`: "Unknown wasi" - - `desktop_env()`: "Unknown wasite" - - `arch()`: "wasm32" + - `realname()`: `$USER` - Fallback "Anonymous" + - `username()`: `$USER` - Fallback "anonymous" + - `lang()`: `$LANGS` - Fallback "en-US" + - `devicename()`: `$NAME` - Fallback "Unknown" + - `hostname()`: `$HOSTNAME` - Fallback "localhost" + - `platform()`: "WASI" + - `distro()`: "Unknown WASI" + - `desktop_env()`: `Unknown($DESKTOP_SESSION)` - Fallback "Unknown WASI" ## Daku (Quantii, other Ardaku environments) WhoAmi will depend on currently unstable portals in the diff --git a/src/os.rs b/src/os.rs index 9b32a71..0220ab7 100644 --- a/src/os.rs +++ b/src/os.rs @@ -19,10 +19,10 @@ all(target_arch = "wasm32", target_os = "daku"), path = "os/fake.rs" )] -// Wasm32 (Wasi) - FIXME: Currently routes to fake.rs +// Wasm32 (Wasi) #[cfg_attr( all(target_arch = "wasm32", target_os = "wasi"), - path = "os/fake.rs" + path = "os/wasi.rs" )] // Wasm32 (Web) #[cfg_attr( diff --git a/src/os/wasi.rs b/src/os/wasi.rs new file mode 100644 index 0000000..9af6cfe --- /dev/null +++ b/src/os/wasi.rs @@ -0,0 +1,80 @@ +#[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))] +compile_error!("Unexpected pointer width for target platform"); + +use std::{env, ffi::OsString}; + +use crate::{ + os::{Os, Target}, + Arch, DesktopEnv, Language, Platform, Result, +}; + +#[inline(always)] +pub(crate) fn lang() -> impl Iterator { + let langs: Vec = wasite::langs() + .unwrap_or_else(|_e| "en_US".to_string()) + .split(';') + .map(|lang| lang.to_string()) + .collect(); + + langs.into_iter() +} + +impl Target for Os { + fn langs(self) -> Vec { + todo!() + } + + #[inline(always)] + fn realname(self) -> Result { + Ok(wasite::user() + .unwrap_or_else(|_e| "Anonymous".to_string()) + .into()) + } + + #[inline(always)] + fn username(self) -> Result { + Ok(wasite::user() + .unwrap_or_else(|_e| "anonymous".to_string()) + .into()) + } + + #[inline(always)] + fn devicename(self) -> Result { + Ok(wasite::name() + .unwrap_or_else(|_e| "Unknown".to_string()) + .into()) + } + + #[inline(always)] + fn hostname(self) -> Result { + Ok(wasite::hostname().unwrap_or_else(|_e| "localhost".to_string())) + } + + #[inline(always)] + fn distro(self) -> Result { + Ok("Unknown WASI".to_string()) + } + + #[inline(always)] + fn desktop_env(self) -> DesktopEnv { + if let Some(ref env) = env::var_os("DESKTOP_SESSION") { + DesktopEnv::Unknown(env.to_string_lossy().to_string()) + } else { + DesktopEnv::Unknown("Unknown WASI".to_string()) + } + } + + #[inline(always)] + fn platform(self) -> Platform { + Platform::Unknown("WASI".to_string()) + } + + #[inline(always)] + fn arch(self) -> Result { + Ok(if cfg!(target_pointer_width = "64") { + Arch::Wasm64 + } else { + Arch::Wasm32 + }) + } +}