proxy_sdk/
env.rs

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    // buf must never be accessed
15
16    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
42/// Get an environment variable value. Subject to whitelists and modifications from Envoy configuration.
43pub fn var(name: impl AsRef<str>) -> Option<&'static str> {
44    ENV_MAP.get(name.as_ref()).copied()
45}
46
47/// Get all environment variable values. Subject to whitelists and modifications from Envoy configuration.
48pub fn vars() -> &'static HashMap<&'static str, &'static str> {
49    &ENV_MAP
50}
51
52/// Get all environment variable values in original ordering. Subject to whitelists and modifications from Envoy configuration.
53pub fn vars_ordered() -> &'static [(String, String)] {
54    &ENV[..]
55}