Skip to main content

aver/services/
env.rs

1/// Env service — environment variables.
2///
3/// Methods:
4///   Env.get(key)        — returns Option<String>
5///   Env.set(key, value) — sets process env var, returns Unit
6///
7/// Effects are granular:
8/// - Env.get
9/// - Env.set
10use std::collections::HashMap;
11
12use crate::value::{RuntimeError, Value};
13
14pub fn register(global: &mut HashMap<String, Value>) {
15    let mut members = HashMap::new();
16    for method in &["get", "set"] {
17        members.insert(
18            method.to_string(),
19            Value::Builtin(format!("Env.{}", method)),
20        );
21    }
22    global.insert(
23        "Env".to_string(),
24        Value::Namespace {
25            name: "Env".to_string(),
26            members,
27        },
28    );
29}
30
31pub fn effects(name: &str) -> &'static [&'static str] {
32    match name {
33        "Env.get" => &["Env.get"],
34        "Env.set" => &["Env.set"],
35        _ => &[],
36    }
37}
38
39pub fn call(name: &str, args: &[Value]) -> Option<Result<Value, RuntimeError>> {
40    match name {
41        "Env.get" => Some(get(args)),
42        "Env.set" => Some(set(args)),
43        _ => None,
44    }
45}
46
47fn get(args: &[Value]) -> Result<Value, RuntimeError> {
48    let [key_val] = args else {
49        return Err(RuntimeError::Error(format!(
50            "Env.get() takes 1 argument (key), got {}",
51            args.len()
52        )));
53    };
54    let Value::Str(key) = key_val else {
55        return Err(RuntimeError::Error(
56            "Env.get: key must be a String".to_string(),
57        ));
58    };
59    match aver_rt::env_get(key) {
60        Some(v) => Ok(Value::Some(Box::new(Value::Str(v)))),
61        None => Ok(Value::None),
62    }
63}
64
65fn set(args: &[Value]) -> Result<Value, RuntimeError> {
66    let [key_val, value_val] = args else {
67        return Err(RuntimeError::Error(format!(
68            "Env.set() takes 2 arguments (key, value), got {}",
69            args.len()
70        )));
71    };
72    let Value::Str(key) = key_val else {
73        return Err(RuntimeError::Error(
74            "Env.set: key must be a String".to_string(),
75        ));
76    };
77    let Value::Str(value) = value_val else {
78        return Err(RuntimeError::Error(
79            "Env.set: value must be a String".to_string(),
80        ));
81    };
82
83    if let Err(e) = aver_rt::env_set(key, value) {
84        return Err(RuntimeError::Error(e));
85    }
86    Ok(Value::Unit)
87}