1use std::sync::Arc;
6
7use fusabi_host::ExecutionContext;
8use fusabi_host::Value;
9
10use crate::safety::SafetyConfig;
11
12pub fn get(
14 safety: &Arc<SafetyConfig>,
15 args: &[Value],
16 _ctx: &ExecutionContext,
17) -> fusabi_host::Result<Value> {
18 let name = args
19 .first()
20 .and_then(|v| v.as_str())
21 .ok_or_else(|| fusabi_host::Error::host_function("env.get: missing name argument"))?;
22
23 safety.check_env(name).map_err(|e| {
25 fusabi_host::Error::host_function(e.to_string())
26 })?;
27
28 match std::env::var(name) {
29 Ok(value) => Ok(Value::String(value)),
30 Err(_) => Ok(Value::Null),
31 }
32}
33
34pub fn set(
36 safety: &Arc<SafetyConfig>,
37 args: &[Value],
38 _ctx: &ExecutionContext,
39) -> fusabi_host::Result<Value> {
40 let name = args
41 .first()
42 .and_then(|v| v.as_str())
43 .ok_or_else(|| fusabi_host::Error::host_function("env.set: missing name argument"))?;
44
45 let value = args
46 .get(1)
47 .and_then(|v| v.as_str())
48 .ok_or_else(|| fusabi_host::Error::host_function("env.set: missing value argument"))?;
49
50 safety.check_env(name).map_err(|e| {
52 fusabi_host::Error::host_function(e.to_string())
53 })?;
54
55 std::env::set_var(name, value);
56 Ok(Value::Null)
57}
58
59pub fn cwd(
61 _args: &[Value],
62 _ctx: &ExecutionContext,
63) -> fusabi_host::Result<Value> {
64 match std::env::current_dir() {
65 Ok(path) => Ok(Value::String(path.to_string_lossy().into_owned())),
66 Err(e) => Err(fusabi_host::Error::host_function(format!("env.cwd: {}", e))),
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use fusabi_host::Capabilities;
74 use fusabi_host::{Sandbox, SandboxConfig};
75 use fusabi_host::Limits;
76
77 fn create_test_ctx() -> ExecutionContext {
78 let sandbox = Sandbox::new(SandboxConfig::default()).unwrap();
79 ExecutionContext::new(1, Capabilities::none(), Limits::default(), sandbox)
80 }
81
82 #[test]
83 fn test_get_safety_check() {
84 let safety = Arc::new(SafetyConfig::strict());
85 let ctx = create_test_ctx();
86
87 let result = get(&safety, &[Value::String("PATH".into())], &ctx);
88 assert!(result.is_err()); }
90
91 #[test]
92 fn test_get_with_permission() {
93 let safety = Arc::new(SafetyConfig::new().with_env_vars(["PATH"]));
94 let ctx = create_test_ctx();
95
96 let result = get(&safety, &[Value::String("PATH".into())], &ctx);
97 assert!(result.is_ok());
98 }
99
100 #[test]
101 fn test_cwd() {
102 let ctx = create_test_ctx();
103 let result = cwd(&[], &ctx);
104 assert!(result.is_ok());
105 assert!(result.unwrap().as_str().is_some());
106 }
107}