1use std::env;
2use std::str::FromStr;
3
4use crate::Error;
5use crate::digest::b64u_decode;
6
7pub fn get_env(name: &str) -> Result<String, Error> {
8 env::var(name).map_err(|_| Error::MissingEnv(name.to_string()))
9}
10
11pub fn get_env_parse<T: FromStr>(name: &str) -> Result<T, Error> {
12 let val = get_env(name)?;
13 val.parse::<T>().map_err(|_| Error::WrongFormat(name.to_string()))
14}
15
16pub fn get_envs() -> Vec<(String, String)> {
17 std::env::vars().collect()
18}
19
20pub fn get_env_b64u_as_u8s(name: &str) -> Result<Vec<u8>, Error> {
21 b64u_decode(&get_env(name)?).map_err(|_| Error::WrongFormat(name.to_string()))
22}
23
24pub fn set_env(name: &str, value: &str) -> Result<(), Error> {
25 std::panic::catch_unwind(|| unsafe {
26 env::set_var(name, value);
27 })
28 .map_err(|e| Error::FailedToSetEnv(name.to_string(), value.to_string(), panic_message(e)))
29}
30
31pub fn remove_env(name: &str) -> Result<(), Error> {
32 std::panic::catch_unwind(|| unsafe {
33 env::remove_var(name);
34 })
35 .map_err(|e| Error::FailedToRemoveEnv(name.to_string(), panic_message(e)))
36}
37
38pub fn remove_envs(names: &[&str]) -> Result<(), Error> {
39 for name in names {
40 remove_env(name)?;
41 }
42 Ok(())
43}
44
45fn panic_message(e: Box<dyn std::any::Any + Send>) -> String {
46 let any = &*e as &dyn std::any::Any;
47 if let Some(s) = any.downcast_ref::<String>() {
48 return s.clone();
49 }
50 if let Some(s) = any.downcast_ref::<&'static str>() {
51 return (*s).to_string();
52 }
53 format!("panic with non-string payload: {:?}", any)
54}