Skip to main content

solti_model/domain/environment/
task.rs

1//! # Task environment
2//!
3//! [`TaskEnv`] is an ordered list attached to a task workload.
4//! Duplicate keys are preserved.
5//! Lookup uses the last matching value.
6//! Keys and values are stored without validation.
7
8env_newtype! {
9    /// Environment variables passed to a task at submission time.
10    ///
11    /// Duplicate keys are allowed. Lookup uses last-value-wins semantics.
12    ///
13    /// ```
14    /// use solti_model::TaskEnv;
15    ///
16    /// let mut env = TaskEnv::new();
17    /// env.push("APP_MODE", "dev");
18    /// env.push("APP_MODE", "prod");
19    ///
20    /// assert_eq!(env.get("APP_MODE"), Some("prod"));
21    /// ```
22    pub struct TaskEnv;
23}
24
25impl TaskEnv {
26    /// Creates an environment with one entry.
27    ///
28    /// ## Example
29    ///
30    /// ```
31    /// use solti_model::TaskEnv;
32    ///
33    /// let env = TaskEnv::single("APP_MODE", "batch");
34    /// assert_eq!(env.get("APP_MODE"), Some("batch"));
35    /// ```
36    #[inline]
37    pub fn single<K, V>(key: K, value: V) -> Self
38    where
39        K: Into<String>,
40        V: Into<String>,
41    {
42        let mut env = Self::new();
43        env.push(key, value);
44        env
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::TaskEnv;
51
52    #[test]
53    fn constructors_iteration_and_lookup_preserve_last_value() {
54        let mut env = TaskEnv::new();
55        assert!(env.is_empty());
56
57        env.push("FOO", "one");
58        env.push("BAR", "x");
59        env.push("FOO", "two");
60
61        assert_eq!(env.len(), 3);
62        assert_eq!(env.iter().next().unwrap().key(), "FOO");
63        assert_eq!(env.get("FOO"), Some("two"));
64        assert_eq!(env.get("BAR"), Some("x"));
65        assert!(env.get("BAZ").is_none());
66
67        let single = TaskEnv::single("ONLY", "value");
68        assert_eq!(single.len(), 1);
69        assert_eq!(single.get("ONLY"), Some("value"));
70    }
71
72    #[test]
73    fn serde_is_transparent_and_preserves_entries() {
74        let mut env = TaskEnv::new();
75        env.push("FOO", "bar");
76        env.push("BAZ", "qux");
77
78        let json = serde_json::to_string(&env).unwrap();
79        assert_eq!(
80            json,
81            r#"[{"key":"FOO","value":"bar"},{"key":"BAZ","value":"qux"}]"#
82        );
83        let back: TaskEnv = serde_json::from_str(&json).unwrap();
84        assert_eq!(back, env);
85    }
86}