Skip to main content

nested_text/
value.rs

1/// The three NestedText value types.
2///
3/// NestedText only has one scalar type (strings). Lists and dicts provide structure.
4/// Dicts use `Vec<(String, Value)>` to preserve insertion order, which NestedText guarantees.
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub enum Value {
7    String(String),
8    List(Vec<Value>),
9    /// Key-value pairs in insertion order.
10    Dict(Vec<(String, Value)>),
11}
12
13impl Value {
14    pub fn as_str(&self) -> Option<&str> {
15        match self {
16            Value::String(s) => Some(s),
17            _ => None,
18        }
19    }
20
21    pub fn as_list(&self) -> Option<&[Value]> {
22        match self {
23            Value::List(v) => Some(v),
24            _ => None,
25        }
26    }
27
28    pub fn as_dict(&self) -> Option<&[(String, Value)]> {
29        match self {
30            Value::Dict(v) => Some(v),
31            _ => None,
32        }
33    }
34
35    pub fn is_string(&self) -> bool {
36        matches!(self, Value::String(_))
37    }
38
39    pub fn is_list(&self) -> bool {
40        matches!(self, Value::List(_))
41    }
42
43    pub fn is_dict(&self) -> bool {
44        matches!(self, Value::Dict(_))
45    }
46
47    /// Look up a key in a dict value. Returns None if not a dict or key not found.
48    pub fn get(&self, key: &str) -> Option<&Value> {
49        match self {
50            Value::Dict(pairs) => pairs.iter().find(|(k, _)| k == key).map(|(_, v)| v),
51            _ => None,
52        }
53    }
54}
55
56impl From<String> for Value {
57    fn from(s: String) -> Self {
58        Value::String(s)
59    }
60}
61
62impl From<&str> for Value {
63    fn from(s: &str) -> Self {
64        Value::String(s.to_string())
65    }
66}
67
68impl From<Vec<Value>> for Value {
69    fn from(v: Vec<Value>) -> Self {
70        Value::List(v)
71    }
72}
73
74impl From<Vec<(String, Value)>> for Value {
75    fn from(v: Vec<(String, Value)>) -> Self {
76        Value::Dict(v)
77    }
78}