use std::collections::HashMap;
use log::error;
use once_cell::sync::Lazy;
#[cfg(target_arch = "wasm32")]
fn read_environment() -> Result<Vec<(String, String)>, wasi::Errno> {
let (count, size) = unsafe { wasi::environ_sizes_get()? };
let mut entries: Vec<*mut u8> = Vec::with_capacity(count);
let mut buf: Vec<u8> = Vec::with_capacity(size);
unsafe { wasi::environ_get(entries.as_mut_ptr(), buf.as_mut_ptr())? };
unsafe { entries.set_len(count) };
let mut out = Vec::new();
for entry in entries {
let cstr = unsafe { std::ffi::CStr::from_ptr(entry as *const i8) }.to_string_lossy();
if let Some((name, value)) = cstr.split_once('=') {
out.push((name.to_string(), value.to_string()));
}
}
Ok(out)
}
#[cfg(not(target_arch = "wasm32"))]
fn read_environment() -> Result<Vec<(String, String)>, std::convert::Infallible> {
Ok(std::env::vars().collect::<Vec<_>>())
}
static ENV: Lazy<Vec<(String, String)>> = Lazy::new(|| match read_environment() {
Ok(x) => x,
Err(e) => {
error!("failed to read environment: {e:?}");
Default::default()
}
});
static ENV_MAP: Lazy<HashMap<&'static str, &'static str>> =
Lazy::new(|| ENV.iter().map(|(k, v)| (&**k, &**v)).collect());
pub fn var(name: impl AsRef<str>) -> Option<&'static str> {
ENV_MAP.get(name.as_ref()).copied()
}
pub fn vars() -> &'static HashMap<&'static str, &'static str> {
&ENV_MAP
}
pub fn vars_ordered() -> &'static [(String, String)] {
&ENV[..]
}