cyberex/env/
eval.rs

1use std::env;
2use std::str::FromStr;
3
4pub fn eval_env_with<T, F>(var_name: &str, default_value: T, parse_fn: F) -> Result<T, T::Err>
5where
6    T: FromStr,
7    F: FnOnce(&str) -> Result<T, T::Err>,
8{
9    let Ok(var_value) = env::var(var_name) else {
10        return Ok(default_value);
11    };
12
13    let parsed = parse_fn(&var_value)?;
14    Ok(parsed)
15}
16
17pub fn eval_env<T>(var_name: &str, default_value: T) -> Result<T, T::Err>
18where
19    T: FromStr,
20{
21    eval_env_with(var_name, default_value, T::from_str)
22}
23
24pub fn eval_env_or<T>(var_name: &str, default_value: T) -> T
25where
26    T: FromStr + Clone,
27{
28    // Note: here ignore the parsed error
29    eval_env(var_name, default_value.clone()).unwrap_or(default_value)
30}
31
32#[cfg(test)]
33mod tests {
34    use std::{
35        net::SocketAddr,
36        path::{Path, PathBuf},
37    };
38
39    use super::*;
40    #[test]
41    fn test_eval_env_or() {
42        {
43            let def = SocketAddr::from(([127, 0, 0, 1], 5423));
44            assert_eq!(eval_env_or::<SocketAddr>("LC_ADDR", def), def);
45        }
46
47        {
48            let def = Path::new("/root/path").to_path_buf();
49            assert_eq!(eval_env_or::<PathBuf>("LC_KEY_DIR", def.clone()), def);
50        }
51        {
52            unsafe { env::set_var("ENABLE", "true") };
53            assert!(eval_env_or::<bool>("ENABLE", false));
54        }
55        {
56            unsafe { env::set_var("LC_ADDR", "localhost:1922") };
57            let def = SocketAddr::from(([127, 0, 0, 1], 5423));
58            // localhost is no ip
59            assert!(eval_env::<SocketAddr>("LC_ADDR", def).is_err());
60        }
61
62        {
63            unsafe { env::set_var("LC_ADDR", "localhost:1922") };
64            let def = SocketAddr::from(([127, 0, 0, 1], 5423));
65            // localhost is no ip
66            assert_eq!(
67                eval_env_with::<SocketAddr, _>("LC_ADDR", def, |s| { s.replace("localhost", "127.0.0.1").parse() })
68                    .unwrap()
69                    .to_string(),
70                "127.0.0.1:1922"
71            );
72        }
73    }
74}