Skip to main content

solti_model/domain/
kv.rs

1//! # Generic key-value pair.
2//!
3//! [`KeyValue`] is used for environment variables and other ordered pair collections.
4
5use serde::{Deserialize, Serialize};
6
7/// Key–value pair used for environment variables or generic metadata.
8#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
9pub struct KeyValue {
10    /// Name of the variable or key.
11    key: String,
12    /// Value associated with the key.
13    value: String,
14}
15
16impl KeyValue {
17    /// Create a new key–value pair.
18    #[inline]
19    pub fn new<K, V>(key: K, value: V) -> Self
20    where
21        K: Into<String>,
22        V: Into<String>,
23    {
24        Self {
25            key: key.into(),
26            value: value.into(),
27        }
28    }
29
30    /// Get the key.
31    #[inline]
32    pub fn key(&self) -> &str {
33        &self.key
34    }
35
36    /// Get the value.
37    #[inline]
38    pub fn value(&self) -> &str {
39        &self.value
40    }
41}
42
43impl From<(String, String)> for KeyValue {
44    #[inline]
45    fn from((key, value): (String, String)) -> Self {
46        Self { key, value }
47    }
48}
49
50impl From<(&str, &str)> for KeyValue {
51    #[inline]
52    fn from((key, value): (&str, &str)) -> Self {
53        Self {
54            key: key.to_string(),
55            value: value.to_string(),
56        }
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::KeyValue;
63
64    #[test]
65    fn new_sets_key_and_value() {
66        let kv = KeyValue::new("FOO", "bar");
67        assert_eq!(kv.key(), "FOO");
68        assert_eq!(kv.value(), "bar");
69    }
70
71    #[test]
72    fn from_str_tuple_creates_keyvalue() {
73        let kv: KeyValue = ("FOO", "bar").into();
74        assert_eq!(kv.key(), "FOO");
75        assert_eq!(kv.value(), "bar");
76    }
77
78    #[test]
79    fn from_string_tuple_creates_keyvalue() {
80        let kv: KeyValue = (String::from("FOO"), String::from("bar")).into();
81        assert_eq!(kv.key(), "FOO");
82        assert_eq!(kv.value(), "bar");
83    }
84
85    #[test]
86    fn equality_works_for_same_key_and_value() {
87        let a = KeyValue::new("FOO", "bar");
88        let b = KeyValue::new("FOO", "bar");
89        let c = KeyValue::new("FOO", "baz");
90
91        assert_eq!(a, b);
92        assert_ne!(a, c);
93    }
94
95    #[test]
96    fn serde_roundtrip_json() {
97        let kv = KeyValue::new("FOO", "bar");
98        let json = serde_json::to_string(&kv).unwrap();
99
100        assert!(json.contains("\"key\":\"FOO\""));
101        assert!(json.contains("\"value\":\"bar\""));
102
103        let back: KeyValue = serde_json::from_str(&json).unwrap();
104        assert_eq!(back.key(), "FOO");
105        assert_eq!(back.value(), "bar");
106    }
107}