anda_config/
context.rs

1use std::collections::BTreeMap;
2
3use hcl::eval::{Context, FuncArgs, FuncDef};
4use hcl::Value;
5
6// once_cell for global context
7use once_cell::sync::OnceCell;
8use parking_lot::Mutex;
9
10// todo: let this be mutable
11static GLOBAL_CONTEXT: OnceCell<Mutex<Context>> = OnceCell::new();
12
13/// Generate Context for HCL evaluation
14///
15/// # Panics
16/// - cannot lock mutex (poison?)
17/// - cannot convert FuncArgs to str
18/// - cannot find FuncArgs as key in environment variables
19pub fn hcl_context() -> Context<'static> {
20    let env_func = |args: FuncArgs| {
21        let env = std::env::vars().collect::<BTreeMap<String, String>>();
22        let key = args.first().and_then(|v| v.as_str()).ok_or("Invalid argument")?;
23        let value = env.get(key).ok_or("Key not found in environment variables")?;
24        Ok(Value::String(value.to_string()))
25    };
26    let c = GLOBAL_CONTEXT.get_or_init(|| {
27        dotenv::dotenv().ok();
28        let mut ctx = Context::new();
29        let env_func = FuncDef::builder().param(hcl::eval::ParamType::String).build(env_func);
30        ctx.declare_func("env", env_func);
31
32        let env = std::env::vars().collect::<BTreeMap<String, String>>();
33        let mut map = hcl::Map::new();
34
35        map.extend(env.into_iter().map(|(k, v)| (k, Value::String(v))));
36
37        ctx.declare_var("env", Value::Object(map));
38
39        Mutex::new(ctx)
40    });
41    c.lock().clone()
42}