agent_first_data/document/
value.rs1use std::collections::BTreeMap;
4
5use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
6
7#[derive(Debug, Clone, PartialEq)]
10pub enum Value {
11 Null,
12 Bool(bool),
13 Integer(i64),
14 Unsigned(u64),
15 Float(f64),
16 Number(String),
31 String(String),
32 Array(Vec<Value>),
33 Object(BTreeMap<String, Value>),
35}
36
37impl Value {
38 #[must_use]
43 pub const fn kind_name(&self) -> &'static str {
44 match self {
45 Self::Null => "null",
46 Self::Bool(_) => "boolean",
47 Self::Integer(_) | Self::Unsigned(_) => "integer",
48 Self::Float(_) => "float",
49 Self::Number(_) => "number",
50 Self::String(_) => "string",
51 Self::Array(_) => "array",
52 Self::Object(_) => "object",
53 }
54 }
55
56 pub fn is_null(&self) -> bool {
57 matches!(self, Value::Null)
58 }
59
60 pub fn is_bool(&self) -> bool {
61 matches!(self, Value::Bool(_))
62 }
63
64 pub fn as_bool(&self) -> Option<bool> {
65 match self {
66 Value::Bool(b) => Some(*b),
67 _ => None,
68 }
69 }
70
71 pub fn is_integer(&self) -> bool {
76 match self {
77 Value::Integer(_) | Value::Unsigned(_) => true,
78 Value::Number(text) => is_integer_literal(text),
79 _ => false,
80 }
81 }
82
83 pub fn as_integer(&self) -> Option<i64> {
88 match self {
89 Value::Integer(i) => Some(*i),
90 _ => None,
91 }
92 }
93
94 pub fn as_unsigned(&self) -> Option<u64> {
95 match self {
96 Value::Unsigned(value) => Some(*value),
97 _ => None,
98 }
99 }
100
101 pub fn is_float(&self) -> bool {
104 match self {
105 Value::Float(_) => true,
106 Value::Number(text) => !is_integer_literal(text),
107 _ => false,
108 }
109 }
110
111 pub fn as_float(&self) -> Option<f64> {
118 match self {
119 Value::Float(f) => Some(*f),
120 Value::Number(text) => text.parse::<f64>().ok(),
121 _ => None,
122 }
123 }
124
125 pub fn is_number_literal(&self) -> bool {
128 matches!(self, Value::Number(_))
129 }
130
131 pub fn as_number_literal(&self) -> Option<&str> {
137 match self {
138 Value::Number(text) => Some(text),
139 _ => None,
140 }
141 }
142
143 pub fn is_string(&self) -> bool {
144 matches!(self, Value::String(_))
145 }
146
147 pub fn as_str(&self) -> Option<&str> {
148 match self {
149 Value::String(s) => Some(s),
150 _ => None,
151 }
152 }
153
154 pub fn is_array(&self) -> bool {
155 matches!(self, Value::Array(_))
156 }
157
158 pub fn as_array(&self) -> Option<&Vec<Value>> {
159 match self {
160 Value::Array(a) => Some(a),
161 _ => None,
162 }
163 }
164
165 pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
166 match self {
167 Value::Array(a) => Some(a),
168 _ => None,
169 }
170 }
171
172 pub fn is_object(&self) -> bool {
173 matches!(self, Value::Object(_))
174 }
175
176 pub fn as_object(&self) -> Option<&BTreeMap<String, Value>> {
177 match self {
178 Value::Object(o) => Some(o),
179 _ => None,
180 }
181 }
182
183 pub fn as_object_mut(&mut self) -> Option<&mut BTreeMap<String, Value>> {
184 match self {
185 Value::Object(o) => Some(o),
186 _ => None,
187 }
188 }
189
190 pub fn get(&self, key: &str) -> Option<&Value> {
191 self.as_object().and_then(|o| o.get(key))
192 }
193
194 pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
195 self.as_object_mut().and_then(|o| o.get_mut(key))
196 }
197}
198
199fn is_integer_literal(text: &str) -> bool {
202 !text.contains(['.', 'e', 'E'])
203}
204
205impl std::fmt::Display for Value {
206 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
207 match self {
208 Value::Null => write!(f, "null"),
209 Value::Bool(b) => write!(f, "{}", b),
210 Value::Integer(i) => write!(f, "{}", i),
211 Value::Unsigned(i) => write!(f, "{}", i),
212 Value::Float(fl) => write!(f, "{}", fl),
213 Value::Number(text) => write!(f, "{text}"),
214 Value::String(s) => write!(f, "\"{}\"", s.escape_default()),
215 Value::Array(_) => write!(f, "[...]"),
216 Value::Object(_) => write!(f, "{{...}}"),
217 }
218 }
219}
220
221impl Serialize for Value {
222 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
223 match self {
224 Value::Null => serializer.serialize_none(),
225 Value::Bool(value) => serializer.serialize_bool(*value),
226 Value::Integer(value) => serializer.serialize_i64(*value),
227 Value::Unsigned(value) => serializer.serialize_u64(*value),
228 Value::Float(value) => serializer.serialize_f64(*value),
229 Value::Number(text) => {
236 if let Ok(i) = text.parse::<i64>() {
237 serializer.serialize_i64(i)
238 } else if let Ok(u) = text.parse::<u64>() {
239 serializer.serialize_u64(u)
240 } else {
241 serializer.serialize_f64(text.parse::<f64>().unwrap_or(0.0))
242 }
243 }
244 Value::String(value) => serializer.serialize_str(value),
245 Value::Array(values) => values.serialize(serializer),
246 Value::Object(values) => values.serialize(serializer),
247 }
248 }
249}
250
251impl<'de> Deserialize<'de> for Value {
252 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
253 struct ValueVisitor;
254
255 impl<'de> de::Visitor<'de> for ValueVisitor {
256 type Value = Value;
257
258 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
259 formatter.write_str("a document value")
260 }
261
262 fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
263 Ok(Value::Null)
264 }
265
266 fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
267 Ok(Value::Null)
268 }
269
270 fn visit_bool<E: de::Error>(self, value: bool) -> Result<Self::Value, E> {
271 Ok(Value::Bool(value))
272 }
273
274 fn visit_i64<E: de::Error>(self, value: i64) -> Result<Self::Value, E> {
275 Ok(Value::Integer(value))
276 }
277
278 fn visit_u64<E: de::Error>(self, value: u64) -> Result<Self::Value, E> {
279 Ok(Value::Unsigned(value))
280 }
281
282 fn visit_f64<E: de::Error>(self, value: f64) -> Result<Self::Value, E> {
283 Ok(Value::Float(value))
284 }
285
286 fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
287 Ok(Value::String(value.to_string()))
288 }
289
290 fn visit_string<E: de::Error>(self, value: String) -> Result<Self::Value, E> {
291 Ok(Value::String(value))
292 }
293
294 fn visit_seq<A: de::SeqAccess<'de>>(
295 self,
296 mut access: A,
297 ) -> Result<Self::Value, A::Error> {
298 let mut values = Vec::new();
299 while let Some(value) = access.next_element()? {
300 values.push(value);
301 }
302 Ok(Value::Array(values))
303 }
304
305 fn visit_map<A: de::MapAccess<'de>>(
306 self,
307 mut access: A,
308 ) -> Result<Self::Value, A::Error> {
309 let mut values = BTreeMap::new();
310 while let Some((key, value)) = access.next_entry()? {
311 values.insert(key, value);
312 }
313 Ok(Value::Object(values))
314 }
315 }
316
317 deserializer.deserialize_any(ValueVisitor)
318 }
319}
320
321mod json_convert {
322 use super::*;
323 use serde_json::json;
324
325 impl From<serde_json::Value> for Value {
326 fn from(v: serde_json::Value) -> Self {
327 match v {
328 serde_json::Value::Null => Value::Null,
329 serde_json::Value::Bool(b) => Value::Bool(b),
330 serde_json::Value::Number(n) => {
331 if let Some(i) = n.as_i64() {
341 Value::Integer(i)
342 } else if let Some(u) = n.as_u64() {
343 Value::Unsigned(u)
344 } else {
345 Value::Number(n.as_str().to_string())
346 }
347 }
348 serde_json::Value::String(s) => Value::String(s),
349 serde_json::Value::Array(a) => {
350 Value::Array(a.into_iter().map(Value::from).collect())
351 }
352 serde_json::Value::Object(o) => {
353 let map = o.into_iter().map(|(k, v)| (k, Value::from(v))).collect();
354 Value::Object(map)
355 }
356 }
357 }
358 }
359
360 impl From<Value> for serde_json::Value {
361 fn from(v: Value) -> Self {
362 match v {
363 Value::Null => serde_json::Value::Null,
364 Value::Bool(b) => json!(b),
365 Value::Integer(i) => json!(i),
366 Value::Unsigned(u) => json!(u),
367 Value::Float(f) => {
368 json!(f)
369 }
370 Value::Number(text) => match serde_json::from_str::<serde_json::Value>(&text) {
380 Ok(number @ serde_json::Value::Number(_)) => number,
381 _ => json!(text.parse::<f64>().unwrap_or(0.0)),
382 },
383 Value::String(s) => json!(s),
384 Value::Array(a) => {
385 let arr: Vec<serde_json::Value> = a.into_iter().map(|v| v.into()).collect();
386 serde_json::Value::Array(arr)
387 }
388 Value::Object(o) => {
389 let mut map = serde_json::Map::new();
390 for (k, v) in o {
391 map.insert(k, serde_json::Value::from(v));
392 }
393 serde_json::Value::Object(map)
394 }
395 }
396 }
397 }
398}
399
400#[cfg(test)]
401mod tests {
402 use super::Value;
403 use std::collections::BTreeMap;
404
405 #[test]
406 fn value_kind_names_are_stable() {
407 let cases = [
408 (Value::Null, "null"),
409 (Value::Bool(true), "boolean"),
410 (Value::Integer(-1), "integer"),
411 (Value::Unsigned(1), "integer"),
412 (Value::Float(1.5), "float"),
413 (Value::Number("1e1000".to_string()), "number"),
414 (Value::String("value".to_string()), "string"),
415 (Value::Array(Vec::new()), "array"),
416 (Value::Object(BTreeMap::new()), "object"),
417 ];
418
419 for (value, expected) in cases {
420 assert_eq!(value.kind_name(), expected);
421 }
422 }
423}