Skip to main content

runmat_runtime/builtins/common/
env.rs

1#[cfg(target_arch = "wasm32")]
2use std::collections::BTreeMap;
3use std::io;
4use std::path::PathBuf;
5#[cfg(target_arch = "wasm32")]
6use std::sync::RwLock;
7
8#[cfg(target_arch = "wasm32")]
9use once_cell::sync::OnceCell;
10
11#[cfg(target_arch = "wasm32")]
12fn default_env_map() -> BTreeMap<String, String> {
13    let mut env = BTreeMap::new();
14    // Match the documented baseline process environment in wasm sessions.
15    env.insert("HOME".to_string(), "/".to_string());
16    env.insert("PATH".to_string(), "/".to_string());
17    env.insert("USER".to_string(), "user".to_string());
18    env
19}
20
21#[cfg(target_arch = "wasm32")]
22fn env_lock() -> &'static RwLock<BTreeMap<String, String>> {
23    static ENV: OnceCell<RwLock<BTreeMap<String, String>>> = OnceCell::new();
24    ENV.get_or_init(|| RwLock::new(default_env_map()))
25}
26
27pub fn var(key: &str) -> io::Result<String> {
28    #[cfg(target_arch = "wasm32")]
29    {
30        let guard = env_lock().read().expect("env lock poisoned");
31        if let Some(value) = guard.get(key) {
32            return Ok(value.clone());
33        }
34        Err(io::Error::new(
35            io::ErrorKind::NotFound,
36            format!("Environment variable not found: {key}"),
37        ))
38    }
39    #[cfg(not(target_arch = "wasm32"))]
40    {
41        std::env::var(key).map_err(|err| io::Error::new(io::ErrorKind::NotFound, err))
42    }
43}
44
45pub fn vars() -> Vec<(String, String)> {
46    #[cfg(target_arch = "wasm32")]
47    {
48        let guard = env_lock().read().expect("env lock poisoned");
49        guard.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
50    }
51    #[cfg(not(target_arch = "wasm32"))]
52    {
53        std::env::vars().collect()
54    }
55}
56
57pub fn set_var(key: &str, value: &str) {
58    #[cfg(target_arch = "wasm32")]
59    {
60        let mut guard = env_lock().write().expect("env lock poisoned");
61        guard.insert(key.to_string(), value.to_string());
62    }
63    #[cfg(not(target_arch = "wasm32"))]
64    {
65        std::env::set_var(key, value);
66    }
67}
68
69pub fn remove_var(key: &str) {
70    #[cfg(target_arch = "wasm32")]
71    {
72        let mut guard = env_lock().write().expect("env lock poisoned");
73        guard.remove(key);
74    }
75    #[cfg(not(target_arch = "wasm32"))]
76    {
77        std::env::remove_var(key);
78    }
79}
80
81pub fn temp_dir() -> PathBuf {
82    #[cfg(target_arch = "wasm32")]
83    {
84        PathBuf::from("/tmp")
85    }
86    #[cfg(not(target_arch = "wasm32"))]
87    {
88        std::env::temp_dir()
89    }
90}