1use crate::handles::ObjectHandle;
8use rust_decimal::Decimal;
9use serde::{Deserialize, Serialize};
10use std::collections::HashMap;
11
12#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
30#[serde(untagged)]
31pub enum Value {
32 #[default]
34 Null,
35 Bool(bool),
37 Int(i64),
39 Float(f64),
41 #[serde(with = "decimal_serde")]
43 Decimal(Decimal),
44 String(String),
46 Array(Vec<Value>),
48 Object(HashMap<String, Value>),
50 #[serde(skip)]
52 ObjectRef(ObjectHandle),
53}
54
55impl Value {
56 pub fn is_null(&self) -> bool {
58 matches!(self, Value::Null)
59 }
60
61 pub fn as_bool(&self) -> Option<bool> {
63 match self {
64 Value::Bool(b) => Some(*b),
65 _ => None,
66 }
67 }
68
69 pub fn as_int(&self) -> Option<i64> {
71 match self {
72 Value::Int(i) => Some(*i),
73 _ => None,
74 }
75 }
76
77 pub fn as_float(&self) -> Option<f64> {
81 match self {
82 Value::Float(f) => Some(*f),
83 Value::Int(i) => Some(*i as f64),
84 _ => None,
85 }
86 }
87
88 pub fn as_decimal(&self) -> Option<Decimal> {
90 match self {
91 Value::Decimal(d) => Some(*d),
92 _ => None,
93 }
94 }
95
96 pub fn as_str(&self) -> Option<&str> {
98 match self {
99 Value::String(s) => Some(s),
100 _ => None,
101 }
102 }
103
104 pub fn as_array(&self) -> Option<&Vec<Value>> {
106 match self {
107 Value::Array(arr) => Some(arr),
108 _ => None,
109 }
110 }
111
112 pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
114 match self {
115 Value::Array(arr) => Some(arr),
116 _ => None,
117 }
118 }
119
120 pub fn as_object(&self) -> Option<&HashMap<String, Value>> {
122 match self {
123 Value::Object(obj) => Some(obj),
124 _ => None,
125 }
126 }
127
128 pub fn as_object_mut(&mut self) -> Option<&mut HashMap<String, Value>> {
130 match self {
131 Value::Object(obj) => Some(obj),
132 _ => None,
133 }
134 }
135
136 pub fn as_object_ref(&self) -> Option<ObjectHandle> {
138 match self {
139 Value::ObjectRef(handle) => Some(*handle),
140 _ => None,
141 }
142 }
143}
144
145impl From<bool> for Value {
146 fn from(b: bool) -> Self {
147 Value::Bool(b)
148 }
149}
150
151impl From<i64> for Value {
152 fn from(i: i64) -> Self {
153 Value::Int(i)
154 }
155}
156
157impl From<i32> for Value {
158 fn from(i: i32) -> Self {
159 Value::Int(i as i64)
160 }
161}
162
163impl From<f64> for Value {
164 fn from(f: f64) -> Self {
165 Value::Float(f)
166 }
167}
168
169impl From<f32> for Value {
170 fn from(f: f32) -> Self {
171 Value::Float(f as f64)
172 }
173}
174
175impl From<Decimal> for Value {
176 fn from(d: Decimal) -> Self {
177 Value::Decimal(d)
178 }
179}
180
181impl From<String> for Value {
182 fn from(s: String) -> Self {
183 Value::String(s)
184 }
185}
186
187impl From<&str> for Value {
188 fn from(s: &str) -> Self {
189 Value::String(s.to_string())
190 }
191}
192
193impl<T: Into<Value>> From<Vec<T>> for Value {
194 fn from(v: Vec<T>) -> Self {
195 Value::Array(v.into_iter().map(Into::into).collect())
196 }
197}
198
199impl From<ObjectHandle> for Value {
200 fn from(handle: ObjectHandle) -> Self {
201 Value::ObjectRef(handle)
202 }
203}
204
205impl<K: Into<String>, V: Into<Value>> FromIterator<(K, V)> for Value {
206 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
207 Value::Object(
208 iter.into_iter()
209 .map(|(k, v)| (k.into(), v.into()))
210 .collect(),
211 )
212 }
213}
214
215impl From<serde_json::Value> for Value {
216 fn from(json: serde_json::Value) -> Self {
217 match json {
218 serde_json::Value::Null => Value::Null,
219 serde_json::Value::Bool(b) => Value::Bool(b),
220 serde_json::Value::Number(n) => {
221 if let Some(i) = n.as_i64() {
222 Value::Int(i)
223 } else if let Some(f) = n.as_f64() {
224 Value::Float(f)
225 } else {
226 Value::Null
227 }
228 }
229 serde_json::Value::String(s) => Value::String(s),
230 serde_json::Value::Array(arr) => {
231 Value::Array(arr.into_iter().map(Value::from).collect())
232 }
233 serde_json::Value::Object(obj) => {
234 Value::Object(obj.into_iter().map(|(k, v)| (k, Value::from(v))).collect())
235 }
236 }
237 }
238}
239
240impl Value {
241 pub fn from_json_value(json: serde_json::Value) -> Self {
243 Self::from(json)
244 }
245}
246
247pub mod decimal_serde {
248 use rust_decimal::Decimal;
249 use serde::{self, Deserialize, Deserializer, Serializer};
250
251 pub fn serialize<S>(decimal: &Decimal, serializer: S) -> Result<S::Ok, S::Error>
252 where
253 S: Serializer,
254 {
255 serializer.serialize_str(&decimal.to_string())
256 }
257
258 pub fn deserialize<'de, D>(deserializer: D) -> Result<Decimal, D::Error>
259 where
260 D: Deserializer<'de>,
261 {
262 let s = String::deserialize(deserializer)?;
263 s.parse().map_err(serde::de::Error::custom)
264 }
265}
266
267#[cfg(test)]
268mod tests {
269 use super::*;
270
271 #[test]
272 fn test_value_conversions() {
273 assert_eq!(Value::from(true), Value::Bool(true));
274 assert_eq!(Value::from(false), Value::Bool(false));
275 assert_eq!(Value::from(42i64), Value::Int(42));
276 assert_eq!(Value::from(42i32), Value::Int(42));
277 assert_eq!(Value::from(3.14f64), Value::Float(3.14));
278 assert_eq!(Value::from(3.14f32), Value::Float(3.14f32 as f64));
279 assert_eq!(Value::from("hello"), Value::String("hello".to_string()));
280 assert_eq!(
281 Value::from("world".to_string()),
282 Value::String("world".to_string())
283 );
284 }
285
286 #[test]
287 fn test_value_accessors() {
288 assert_eq!(Value::Bool(true).as_bool(), Some(true));
289 assert_eq!(Value::Bool(false).as_bool(), Some(false));
290 assert_eq!(Value::Int(42).as_int(), Some(42));
291 assert_eq!(Value::Float(3.14).as_float(), Some(3.14));
292 assert_eq!(Value::Int(42).as_float(), Some(42.0)); assert_eq!(Value::String("hello".to_string()).as_str(), Some("hello"));
294 }
295
296 #[test]
297 fn test_null_check() {
298 assert!(Value::Null.is_null());
299 assert!(!Value::Bool(false).is_null());
300 assert!(!Value::Int(0).is_null());
301 }
302
303 #[test]
304 fn test_default() {
305 let val: Value = Default::default();
306 assert!(val.is_null());
307 }
308
309 #[test]
310 fn test_array_conversion() {
311 let arr = Value::from(vec![1i64, 2, 3]);
312 assert_eq!(
313 arr.as_array(),
314 Some(&vec![Value::Int(1), Value::Int(2), Value::Int(3)])
315 );
316 }
317
318 #[test]
319 fn test_object_from_iterator() {
320 let obj: Value = vec![("key1", 42i64), ("key2", 99i64)].into_iter().collect();
321 let map = obj.as_object().unwrap();
322 assert_eq!(map.get("key1"), Some(&Value::Int(42)));
323 assert_eq!(map.get("key2"), Some(&Value::Int(99)));
324 }
325
326 #[test]
327 fn test_object_handle_conversion() {
328 let handle = ObjectHandle::new(123);
329 let val = Value::from(handle);
330 assert_eq!(val.as_object_ref(), Some(ObjectHandle::new(123)));
331 }
332
333 #[test]
334 fn test_decimal_conversion() {
335 let d = Decimal::new(314, 2); let val = Value::from(d);
337 assert_eq!(val.as_decimal(), Some(Decimal::new(314, 2)));
338 }
339
340 #[test]
341 fn test_json_serialization_primitives() {
342 assert_eq!(serde_json::to_string(&Value::Null).unwrap(), "null");
343 assert_eq!(serde_json::to_string(&Value::Bool(true)).unwrap(), "true");
344 assert_eq!(serde_json::to_string(&Value::Int(42)).unwrap(), "42");
345 assert_eq!(serde_json::to_string(&Value::Float(3.14)).unwrap(), "3.14");
346 assert_eq!(
347 serde_json::to_string(&Value::String("hello".to_string())).unwrap(),
348 "\"hello\""
349 );
350 }
351
352 #[test]
353 fn test_json_serialization_array() {
354 let arr = Value::Array(vec![Value::Int(1), Value::Int(2), Value::Int(3)]);
355 assert_eq!(serde_json::to_string(&arr).unwrap(), "[1,2,3]");
356 }
357
358 #[test]
359 fn test_json_serialization_object() {
360 let mut map = HashMap::new();
361 map.insert("a".to_string(), Value::Int(1));
362 let obj = Value::Object(map);
363 assert_eq!(serde_json::to_string(&obj).unwrap(), "{\"a\":1}");
364 }
365
366 #[test]
367 fn test_json_deserialization() {
368 assert_eq!(serde_json::from_str::<Value>("null").unwrap(), Value::Null);
369 assert_eq!(
370 serde_json::from_str::<Value>("true").unwrap(),
371 Value::Bool(true)
372 );
373 assert_eq!(serde_json::from_str::<Value>("42").unwrap(), Value::Int(42));
374 assert_eq!(
375 serde_json::from_str::<Value>("\"hello\"").unwrap(),
376 Value::String("hello".to_string())
377 );
378 }
379
380 #[test]
381 fn test_mutable_accessors() {
382 let mut arr = Value::Array(vec![Value::Int(1)]);
383 arr.as_array_mut().unwrap().push(Value::Int(2));
384 assert_eq!(arr.as_array().unwrap().len(), 2);
385
386 let mut obj: Value = vec![("key", 1i64)].into_iter().collect();
387 obj.as_object_mut()
388 .unwrap()
389 .insert("key2".to_string(), Value::Int(2));
390 assert_eq!(obj.as_object().unwrap().len(), 2);
391 }
392
393 #[test]
394 fn test_accessor_returns_none_for_wrong_type() {
395 let val = Value::Int(42);
396 assert_eq!(val.as_bool(), None);
397 assert_eq!(val.as_str(), None);
398 assert_eq!(val.as_array(), None);
399 assert_eq!(val.as_object(), None);
400 assert_eq!(val.as_object_ref(), None);
401 }
402}