Skip to main content

agent_first_data/document/
value.rs

1//! Custom Value type — zero external format dependencies.
2
3use std::collections::BTreeMap;
4
5use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
6
7/// Custom Value IR independent of any format crate.
8/// Supports all formats: JSON, TOML, YAML, dotenv, and INI.
9#[derive(Debug, Clone, PartialEq)]
10pub enum Value {
11    Null,
12    Bool(bool),
13    Integer(i64),
14    Unsigned(u64),
15    Float(f64),
16    String(String),
17    Array(Vec<Value>),
18    /// Object map. Keys are stored sorted (BTreeMap), not in insertion order.
19    Object(BTreeMap<String, Value>),
20}
21
22impl Value {
23    pub fn is_null(&self) -> bool {
24        matches!(self, Value::Null)
25    }
26
27    pub fn is_bool(&self) -> bool {
28        matches!(self, Value::Bool(_))
29    }
30
31    pub fn as_bool(&self) -> Option<bool> {
32        match self {
33            Value::Bool(b) => Some(*b),
34            _ => None,
35        }
36    }
37
38    pub fn is_integer(&self) -> bool {
39        matches!(self, Value::Integer(_) | Value::Unsigned(_))
40    }
41
42    pub fn as_integer(&self) -> Option<i64> {
43        match self {
44            Value::Integer(i) => Some(*i),
45            _ => None,
46        }
47    }
48
49    pub fn as_unsigned(&self) -> Option<u64> {
50        match self {
51            Value::Unsigned(value) => Some(*value),
52            _ => None,
53        }
54    }
55
56    pub fn is_float(&self) -> bool {
57        matches!(self, Value::Float(_))
58    }
59
60    pub fn as_float(&self) -> Option<f64> {
61        match self {
62            Value::Float(f) => Some(*f),
63            _ => None,
64        }
65    }
66
67    pub fn is_string(&self) -> bool {
68        matches!(self, Value::String(_))
69    }
70
71    pub fn as_str(&self) -> Option<&str> {
72        match self {
73            Value::String(s) => Some(s),
74            _ => None,
75        }
76    }
77
78    pub fn is_array(&self) -> bool {
79        matches!(self, Value::Array(_))
80    }
81
82    pub fn as_array(&self) -> Option<&Vec<Value>> {
83        match self {
84            Value::Array(a) => Some(a),
85            _ => None,
86        }
87    }
88
89    pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
90        match self {
91            Value::Array(a) => Some(a),
92            _ => None,
93        }
94    }
95
96    pub fn is_object(&self) -> bool {
97        matches!(self, Value::Object(_))
98    }
99
100    pub fn as_object(&self) -> Option<&BTreeMap<String, Value>> {
101        match self {
102            Value::Object(o) => Some(o),
103            _ => None,
104        }
105    }
106
107    pub fn as_object_mut(&mut self) -> Option<&mut BTreeMap<String, Value>> {
108        match self {
109            Value::Object(o) => Some(o),
110            _ => None,
111        }
112    }
113
114    pub fn get(&self, key: &str) -> Option<&Value> {
115        self.as_object().and_then(|o| o.get(key))
116    }
117
118    pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
119        self.as_object_mut().and_then(|o| o.get_mut(key))
120    }
121}
122
123impl std::fmt::Display for Value {
124    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125        match self {
126            Value::Null => write!(f, "null"),
127            Value::Bool(b) => write!(f, "{}", b),
128            Value::Integer(i) => write!(f, "{}", i),
129            Value::Unsigned(i) => write!(f, "{}", i),
130            Value::Float(fl) => write!(f, "{}", fl),
131            Value::String(s) => write!(f, "\"{}\"", s.escape_default()),
132            Value::Array(_) => write!(f, "[...]"),
133            Value::Object(_) => write!(f, "{{...}}"),
134        }
135    }
136}
137
138impl Serialize for Value {
139    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
140        match self {
141            Value::Null => serializer.serialize_none(),
142            Value::Bool(value) => serializer.serialize_bool(*value),
143            Value::Integer(value) => serializer.serialize_i64(*value),
144            Value::Unsigned(value) => serializer.serialize_u64(*value),
145            Value::Float(value) => serializer.serialize_f64(*value),
146            Value::String(value) => serializer.serialize_str(value),
147            Value::Array(values) => values.serialize(serializer),
148            Value::Object(values) => values.serialize(serializer),
149        }
150    }
151}
152
153impl<'de> Deserialize<'de> for Value {
154    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
155        struct ValueVisitor;
156
157        impl<'de> de::Visitor<'de> for ValueVisitor {
158            type Value = Value;
159
160            fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
161                formatter.write_str("a configuration value")
162            }
163
164            fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
165                Ok(Value::Null)
166            }
167
168            fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
169                Ok(Value::Null)
170            }
171
172            fn visit_bool<E: de::Error>(self, value: bool) -> Result<Self::Value, E> {
173                Ok(Value::Bool(value))
174            }
175
176            fn visit_i64<E: de::Error>(self, value: i64) -> Result<Self::Value, E> {
177                Ok(Value::Integer(value))
178            }
179
180            fn visit_u64<E: de::Error>(self, value: u64) -> Result<Self::Value, E> {
181                Ok(Value::Unsigned(value))
182            }
183
184            fn visit_f64<E: de::Error>(self, value: f64) -> Result<Self::Value, E> {
185                Ok(Value::Float(value))
186            }
187
188            fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
189                Ok(Value::String(value.to_string()))
190            }
191
192            fn visit_string<E: de::Error>(self, value: String) -> Result<Self::Value, E> {
193                Ok(Value::String(value))
194            }
195
196            fn visit_seq<A: de::SeqAccess<'de>>(
197                self,
198                mut access: A,
199            ) -> Result<Self::Value, A::Error> {
200                let mut values = Vec::new();
201                while let Some(value) = access.next_element()? {
202                    values.push(value);
203                }
204                Ok(Value::Array(values))
205            }
206
207            fn visit_map<A: de::MapAccess<'de>>(
208                self,
209                mut access: A,
210            ) -> Result<Self::Value, A::Error> {
211                let mut values = BTreeMap::new();
212                while let Some((key, value)) = access.next_entry()? {
213                    values.insert(key, value);
214                }
215                Ok(Value::Object(values))
216            }
217        }
218
219        deserializer.deserialize_any(ValueVisitor)
220    }
221}
222
223mod json_convert {
224    use super::*;
225    use serde_json::json;
226
227    impl From<serde_json::Value> for Value {
228        fn from(v: serde_json::Value) -> Self {
229            match v {
230                serde_json::Value::Null => Value::Null,
231                serde_json::Value::Bool(b) => Value::Bool(b),
232                serde_json::Value::Number(n) => {
233                    if let Some(i) = n.as_i64() {
234                        Value::Integer(i)
235                    } else if let Some(u) = n.as_u64() {
236                        Value::Unsigned(u)
237                    } else {
238                        Value::Float(n.as_f64().unwrap_or(0.0))
239                    }
240                }
241                serde_json::Value::String(s) => Value::String(s),
242                serde_json::Value::Array(a) => {
243                    Value::Array(a.into_iter().map(Value::from).collect())
244                }
245                serde_json::Value::Object(o) => {
246                    let map = o.into_iter().map(|(k, v)| (k, Value::from(v))).collect();
247                    Value::Object(map)
248                }
249            }
250        }
251    }
252
253    impl From<Value> for serde_json::Value {
254        fn from(v: Value) -> Self {
255            match v {
256                Value::Null => serde_json::Value::Null,
257                Value::Bool(b) => json!(b),
258                Value::Integer(i) => json!(i),
259                Value::Unsigned(u) => json!(u),
260                Value::Float(f) => {
261                    json!(f)
262                }
263                Value::String(s) => json!(s),
264                Value::Array(a) => {
265                    let arr: Vec<serde_json::Value> = a.into_iter().map(|v| v.into()).collect();
266                    serde_json::Value::Array(arr)
267                }
268                Value::Object(o) => {
269                    let mut map = serde_json::Map::new();
270                    for (k, v) in o {
271                        map.insert(k, serde_json::Value::from(v));
272                    }
273                    serde_json::Value::Object(map)
274                }
275            }
276        }
277    }
278}