1use std::collections::HashMap;
2
3use log::error;
4use once_cell::sync::Lazy;
5
6#[cfg(target_arch = "wasm32")]
7fn read_environment() -> Result<Vec<(String, String)>, wasi::Errno> {
8 let (count, size) = unsafe { wasi::environ_sizes_get()? };
9 let mut entries: Vec<*mut u8> = Vec::with_capacity(count);
10
11 let mut buf: Vec<u8> = Vec::with_capacity(size);
12 unsafe { wasi::environ_get(entries.as_mut_ptr(), buf.as_mut_ptr())? };
13 unsafe { entries.set_len(count) };
14 let mut out = Vec::new();
17 for entry in entries {
18 let cstr = unsafe { std::ffi::CStr::from_ptr(entry as *const i8) }.to_string_lossy();
19 if let Some((name, value)) = cstr.split_once('=') {
20 out.push((name.to_string(), value.to_string()));
21 }
22 }
23
24 Ok(out)
25}
26
27#[cfg(not(target_arch = "wasm32"))]
28fn read_environment() -> Result<Vec<(String, String)>, std::convert::Infallible> {
29 Ok(std::env::vars().collect::<Vec<_>>())
30}
31
32static ENV: Lazy<Vec<(String, String)>> = Lazy::new(|| match read_environment() {
33 Ok(x) => x,
34 Err(e) => {
35 error!("failed to read environment: {e:?}");
36 Default::default()
37 }
38});
39static ENV_MAP: Lazy<HashMap<&'static str, &'static str>> =
40 Lazy::new(|| ENV.iter().map(|(k, v)| (&**k, &**v)).collect());
41
42pub fn var(name: impl AsRef<str>) -> Option<&'static str> {
44 ENV_MAP.get(name.as_ref()).copied()
45}
46
47pub fn vars() -> &'static HashMap<&'static str, &'static str> {
49 &ENV_MAP
50}
51
52pub fn vars_ordered() -> &'static [(String, String)] {
54 &ENV[..]
55}