Skip to main content

solti_model/domain/environment/
task.rs

1//! # Task-level environment variables.
2//!
3//! [`TaskEnv`] is an ordered list of key-value pairs attached to a single task spec.
4
5env_newtype! {
6    /// Environment variables passed to a task at submission time.
7    ///
8    /// ```text
9    ///  TaskSpec
10    ///  ┌───────────────────────────────┐
11    ///  │  kind: Subprocess {           │
12    ///  │    env: TaskEnv [             │
13    ///  │      FOO=from-task,           │  ← user-defined
14    ///  │      BAR=task-only,           │
15    ///  │    ]                          │
16    ///  │  }                            │
17    ///  └───────────────────────────────┘
18    /// ```
19    pub struct TaskEnv;
20}
21
22impl TaskEnv {
23    /// Create an environment containing a single key–value pair.
24    #[inline]
25    pub fn single<K, V>(key: K, value: V) -> Self
26    where
27        K: Into<String>,
28        V: Into<String>,
29    {
30        let mut env = Self::new();
31        env.push(key, value);
32        env
33    }
34}
35
36#[cfg(test)]
37mod tests {
38    use super::TaskEnv;
39
40    #[test]
41    fn env_new_is_empty() {
42        let env = TaskEnv::new();
43
44        assert_eq!(env.len(), 0);
45        assert!(env.get("FOO").is_none());
46    }
47
48    #[test]
49    fn env_single_creates_one_entry() {
50        let env = TaskEnv::single("FOO", "bar");
51        let items: Vec<_> = env.iter().collect();
52
53        assert_eq!(items.len(), 1);
54        assert_eq!(items[0].key(), "FOO");
55        assert_eq!(items[0].value(), "bar");
56        assert_eq!(env.get("FOO"), Some("bar"));
57    }
58
59    #[test]
60    fn env_push_and_override_last_wins() {
61        let mut env = TaskEnv::new();
62        env.push("FOO", "one");
63        env.push("BAR", "x");
64        env.push("FOO", "two");
65
66        assert_eq!(env.get("FOO"), Some("two"));
67        assert_eq!(env.get("BAR"), Some("x"));
68        assert!(env.get("BAZ").is_none());
69    }
70
71    #[test]
72    fn serde_transparent_roundtrip_json() {
73        let mut env = TaskEnv::new();
74        env.push("FOO", "bar");
75        env.push("BAZ", "qux");
76
77        let json = serde_json::to_string(&env).unwrap();
78        assert!(json.starts_with('['));
79        assert!(json.contains("\"key\":\"FOO\""));
80        assert!(json.contains("\"value\":\"bar\""));
81
82        let back: TaskEnv = serde_json::from_str(&json).unwrap();
83        assert_eq!(back.get("FOO"), Some("bar"));
84        assert_eq!(back.get("BAZ"), Some("qux"));
85    }
86}