1use std::{borrow::Cow, collections::BTreeMap};
2
3mod binary;
4pub use binary::Binary;
5mod timestamp;
6pub use timestamp::Timestamp;
7
8#[cfg(feature = "serde")]
9pub mod de;
10#[cfg(feature = "serde")]
11pub mod ser;
12
13#[derive(Debug, Clone, PartialEq, Default)]
15pub enum Value {
16 #[default]
18 Null,
19 Bool(bool),
21 Int(i64),
23 Float(f64),
25 String(String),
27 Binary(Binary),
29 Timestamp(Timestamp),
31 List(Vec<Value>),
33 Map(BTreeMap<String, Value>),
35}
36
37impl std::fmt::Display for Value {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 write!(f, "{:?}", self)
43 }
44}
45
46impl Value {
47 pub fn is_null(&self) -> bool {
49 matches!(self, Value::Null)
50 }
51
52 pub fn is_bool(&self) -> bool {
54 matches!(self, Value::Bool(_))
55 }
56
57 pub fn is_int(&self) -> bool {
59 matches!(self, Value::Int(_))
60 }
61
62 pub fn is_float(&self) -> bool {
64 matches!(self, Value::Float(_))
65 }
66
67 pub fn is_string(&self) -> bool {
69 matches!(self, Value::String(_))
70 }
71
72 pub fn is_binary(&self) -> bool {
74 matches!(self, Value::Binary(_))
75 }
76
77 pub fn is_timestamp(&self) -> bool {
79 matches!(self, Value::Timestamp(_))
80 }
81
82 pub fn is_list(&self) -> bool {
84 matches!(self, Value::List(_))
85 }
86
87 pub fn is_map(&self) -> bool {
89 matches!(self, Value::Map(_))
90 }
91
92 pub fn as_bool(&self) -> Option<bool> {
94 match self {
95 Value::Bool(b) => Some(*b),
96 _ => None,
97 }
98 }
99
100 pub fn as_int(&self) -> Option<i64> {
102 match self {
103 Value::Int(i) => Some(*i),
104 _ => None,
105 }
106 }
107
108 pub fn as_float(&self) -> Option<f64> {
110 match self {
111 Value::Float(f) => Some(*f),
112 _ => None,
113 }
114 }
115
116 pub fn as_string(&self) -> Option<&str> {
118 match self {
119 Value::String(s) => Some(s),
120 _ => None,
121 }
122 }
123
124 pub fn as_binary(&self) -> Option<&Binary> {
126 match self {
127 Value::Binary(b) => Some(b),
128 _ => None,
129 }
130 }
131
132 pub fn as_timestamp(&self) -> Option<&Timestamp> {
134 match self {
135 Value::Timestamp(t) => Some(t),
136 _ => None,
137 }
138 }
139
140 pub fn as_list(&self) -> Option<&[Value]> {
142 match self {
143 Value::List(l) => Some(l),
144 _ => None,
145 }
146 }
147
148 pub fn as_map(&self) -> Option<&BTreeMap<String, Value>> {
150 match self {
151 Value::Map(m) => Some(m),
152 _ => None,
153 }
154 }
155
156 pub fn as_list_mut(&mut self) -> Option<&mut Vec<Value>> {
158 match self {
159 Value::List(l) => Some(l),
160 _ => None,
161 }
162 }
163
164 pub fn as_map_mut(&mut self) -> Option<&mut BTreeMap<String, Value>> {
166 match self {
167 Value::Map(m) => Some(m),
168 _ => None,
169 }
170 }
171
172 pub fn take(&mut self) -> Value {
174 std::mem::replace(self, Value::Null)
175 }
176}
177
178impl From<()> for Value {
179 fn from(_: ()) -> Self {
180 Value::Null
181 }
182}
183
184impl From<bool> for Value {
185 fn from(value: bool) -> Self {
186 Value::Bool(value)
187 }
188}
189
190impl From<i64> for Value {
191 fn from(value: i64) -> Self {
192 Value::Int(value)
193 }
194}
195
196impl From<f64> for Value {
197 fn from(value: f64) -> Self {
198 Value::Float(value)
199 }
200}
201
202impl From<String> for Value {
203 fn from(value: String) -> Self {
204 Value::String(value)
205 }
206}
207
208impl From<&str> for Value {
209 fn from(value: &str) -> Self {
210 Value::String(value.to_string())
211 }
212}
213
214impl<'a> From<Cow<'a, str>> for Value {
215 fn from(value: Cow<'a, str>) -> Self {
216 Value::String(value.into_owned())
217 }
218}
219
220impl From<Binary> for Value {
221 fn from(value: Binary) -> Self {
222 Value::Binary(value)
223 }
224}
225
226impl From<Timestamp> for Value {
227 fn from(value: Timestamp) -> Self {
228 Value::Timestamp(value)
229 }
230}
231
232impl<V> From<Vec<V>> for Value
233where
234 V: Into<Value>,
235{
236 fn from(vec: Vec<V>) -> Self {
237 vec.into_iter().collect()
238 }
239}
240
241impl<V> From<&[V]> for Value
242where
243 V: Into<Value> + Clone,
244{
245 fn from(slice: &[V]) -> Self {
246 slice.iter().cloned().collect()
247 }
248}
249
250impl<V, const N: usize> From<[V; N]> for Value
251where
252 V: Into<Value>,
253{
254 fn from(arr: [V; N]) -> Self {
255 arr.into_iter().collect()
256 }
257}
258
259impl<V, const N: usize> From<&[V; N]> for Value
260where
261 V: Into<Value> + Clone,
262{
263 fn from(arr: &[V; N]) -> Self {
264 arr.iter().cloned().collect()
265 }
266}
267
268impl<V> FromIterator<V> for Value
269where
270 V: Into<Value>,
271{
272 fn from_iter<I: IntoIterator<Item = V>>(iter: I) -> Self {
273 Value::List(iter.into_iter().map(Into::into).collect())
274 }
275}
276
277impl<K, V> FromIterator<(K, V)> for Value
278where
279 K: Into<String>,
280 V: Into<Value>,
281{
282 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
283 Value::Map(
284 iter.into_iter()
285 .map(|(k, v)| (k.into(), v.into()))
286 .collect(),
287 )
288 }
289}
290
291impl<K, V> From<&[(K, V)]> for Value
292where
293 K: Into<String> + Clone,
294 V: Into<Value> + Clone,
295{
296 fn from(slice: &[(K, V)]) -> Self {
297 slice.iter().cloned().collect()
298 }
299}
300
301impl<K, V, const N: usize> From<[(K, V); N]> for Value
302where
303 K: Into<String>,
304 V: Into<Value>,
305{
306 fn from(arr: [(K, V); N]) -> Self {
307 arr.into_iter().collect()
308 }
309}
310
311impl<K, V, const N: usize> From<&[(K, V); N]> for Value
312where
313 K: Into<String> + Clone,
314 V: Into<Value> + Clone,
315{
316 fn from(arr: &[(K, V); N]) -> Self {
317 arr.iter().cloned().collect()
318 }
319}
320
321impl<V> From<Option<V>> for Value
322where
323 V: Into<Value>,
324{
325 fn from(opt: Option<V>) -> Self {
326 match opt {
327 Some(v) => v.into(),
328 None => Value::Null,
329 }
330 }
331}
332
333impl PartialEq<str> for Value {
334 fn eq(&self, other: &str) -> bool {
335 self.as_string() == Some(other)
336 }
337}
338
339impl PartialEq<&str> for Value {
340 fn eq(&self, other: &&str) -> bool {
341 self.as_string() == Some(*other)
342 }
343}
344
345impl PartialEq<String> for Value {
346 fn eq(&self, other: &String) -> bool {
347 self.as_string() == Some(other.as_str())
348 }
349}
350
351impl PartialEq<i64> for Value {
352 fn eq(&self, other: &i64) -> bool {
353 self.as_int() == Some(*other)
354 }
355}
356
357impl PartialEq<f64> for Value {
358 fn eq(&self, other: &f64) -> bool {
359 self.as_float() == Some(*other)
360 }
361}
362
363impl PartialEq<bool> for Value {
364 fn eq(&self, other: &bool) -> bool {
365 self.as_bool() == Some(*other)
366 }
367}
368
369#[cfg(test)]
370mod tests {
371 use rstest::rstest;
372
373 use super::*;
374
375 #[rstest]
376 #[case(Value::Null, "null")]
377 #[case(Value::Bool(true), "bool")]
378 #[case(Value::Int(42), "int")]
379 #[case(Value::Float(2.5), "float")]
380 #[case(Value::String("hello".to_string()), "string")]
381 #[case(Value::Binary(Binary(vec![1, 2, 3])), "binary")]
382 #[case(Value::Timestamp(Timestamp::from_unix_timestamp(1234567890).unwrap()), "timestamp")]
383 #[case(Value::List(vec![Value::Null]), "list")]
384 #[case(Value::Map(BTreeMap::new()), "map")]
385 fn test_is_methods(#[case] value: Value, #[case] value_type: &str) {
386 assert_eq!(value.is_null(), value_type == "null");
387 assert_eq!(value.is_bool(), value_type == "bool");
388 assert_eq!(value.is_int(), value_type == "int");
389 assert_eq!(value.is_float(), value_type == "float");
390 assert_eq!(value.is_string(), value_type == "string");
391 assert_eq!(value.is_binary(), value_type == "binary");
392 assert_eq!(value.is_timestamp(), value_type == "timestamp");
393 assert_eq!(value.is_list(), value_type == "list");
394 assert_eq!(value.is_map(), value_type == "map");
395 }
396
397 #[test]
398 fn test_as_bool() {
399 assert_eq!(Value::Bool(true).as_bool(), Some(true));
400 assert_eq!(Value::Null.as_bool(), None);
401 }
402
403 #[test]
404 fn test_as_int() {
405 assert_eq!(Value::Int(42).as_int(), Some(42));
406 assert_eq!(Value::Float(2.5).as_int(), None);
407 }
408
409 #[test]
410 fn test_as_float() {
411 assert_eq!(Value::Float(2.5).as_float(), Some(2.5));
412 assert_eq!(Value::Int(42).as_float(), None);
413 }
414
415 #[test]
416 fn test_as_string() {
417 assert_eq!(
418 Value::String("hello".to_string()).as_string(),
419 Some("hello")
420 );
421 assert_eq!(Value::Null.as_string(), None);
422 }
423
424 #[test]
425 fn test_as_binary() {
426 let binary = Binary(vec![1, 2, 3]);
427 let binary_val = Value::Binary(binary.clone());
428 assert_eq!(binary_val.as_binary(), Some(&binary));
429 assert_eq!(Value::Null.as_binary(), None);
430 }
431
432 #[test]
433 fn test_as_timestamp() {
434 let ts = Timestamp::from_unix_timestamp(1234567890).unwrap();
435 let ts_val = Value::Timestamp(ts);
436 assert_eq!(ts_val.as_timestamp(), Some(&ts));
437 assert_eq!(Value::Int(42).as_timestamp(), None);
438 }
439
440 #[test]
441 fn test_as_list() {
442 let list = vec![Value::Int(1), Value::Int(2)];
443 let list_val = Value::List(list.clone());
444 assert_eq!(list_val.as_list(), Some(list.as_slice()));
445 assert_eq!(Value::Null.as_list(), None);
446 }
447
448 #[test]
449 fn test_as_map() {
450 let mut map = BTreeMap::new();
451 map.insert("key".to_string(), Value::Int(42));
452 let map_val = Value::Map(map.clone());
453 assert_eq!(map_val.as_map(), Some(&map));
454 assert_eq!(Value::Null.as_map(), None);
455 }
456
457 #[rstest]
458 #[case(Value::from(()), Value::Null)]
459 #[case(Value::from(true), Value::Bool(true))]
460 #[case(Value::from(42i64), Value::Int(42))]
461 #[case(Value::from(2.5f64), Value::Float(2.5))]
462 #[case(Value::from("hello".to_string()), Value::String("hello".to_string()))]
463 #[case(Value::from("world"), Value::String("world".to_string()))]
464 fn test_from_primitives(#[case] actual: Value, #[case] expected: Value) {
465 assert_eq!(actual, expected);
466 }
467
468 #[test]
469 fn test_from_conversions() {
470 let owned: Cow<str> = Cow::Owned("owned".to_string());
474 assert_eq!(Value::from(owned), Value::String("owned".to_string()));
475 let borrowed: Cow<str> = Cow::Borrowed("borrowed");
476 assert_eq!(Value::from(borrowed), Value::String("borrowed".to_string()));
477
478 let binary = Binary(vec![1, 2, 3]);
480 assert_eq!(Value::from(binary.clone()), Value::Binary(binary));
481
482 let dt = Timestamp::from_unix_timestamp(1234567890).unwrap();
484 assert_eq!(Value::from(dt), Value::Timestamp(dt));
485
486 let value = Value::Binary(b"data".into());
488 assert_eq!(value, Value::Binary(Binary(b"data".to_vec())));
489
490 let vec = vec![1i64, 2, 3];
492 let list_val = Value::from(vec);
493 assert_eq!(
494 list_val,
495 Value::List(vec![Value::Int(1), Value::Int(2), Value::Int(3)])
496 );
497
498 let slice: &[i64] = &[1, 2, 3];
500 let list_val = Value::from(slice);
501 assert_eq!(
502 list_val,
503 Value::List(vec![Value::Int(1), Value::Int(2), Value::Int(3)])
504 );
505
506 let list_val: Value = vec![1i64, 2, 3].into_iter().collect();
508 assert_eq!(
509 list_val,
510 Value::List(vec![Value::Int(1), Value::Int(2), Value::Int(3)])
511 );
512
513 let map_val: Value = vec![("a", 1i64), ("b", 2)].into_iter().collect();
515 let mut expected_map = BTreeMap::new();
516 expected_map.insert("a".to_string(), Value::Int(1));
517 expected_map.insert("b".to_string(), Value::Int(2));
518 assert_eq!(map_val, Value::Map(expected_map));
519
520 let slice: &[(&str, i64)] = &[("x", 10), ("y", 20)];
522 let map_val = Value::from(slice);
523 let mut expected_map = BTreeMap::new();
524 expected_map.insert("x".to_string(), Value::Int(10));
525 expected_map.insert("y".to_string(), Value::Int(20));
526 assert_eq!(map_val, Value::Map(expected_map));
527
528 let list_val = Value::from([1i64, 2, 3]);
530 assert_eq!(
531 list_val,
532 Value::List(vec![Value::Int(1), Value::Int(2), Value::Int(3)])
533 );
534
535 let arr = [4i64, 5, 6];
537 let list_val = Value::from(&arr);
538 assert_eq!(
539 list_val,
540 Value::List(vec![Value::Int(4), Value::Int(5), Value::Int(6)])
541 );
542
543 let map_val = Value::from([("a", 1i64), ("b", 2)]);
545 let mut expected_map = BTreeMap::new();
546 expected_map.insert("a".to_string(), Value::Int(1));
547 expected_map.insert("b".to_string(), Value::Int(2));
548 assert_eq!(map_val, Value::Map(expected_map));
549
550 let arr = [("c", 3i64), ("d", 4)];
552 let map_val = Value::from(&arr);
553 let mut expected_map = BTreeMap::new();
554 expected_map.insert("c".to_string(), Value::Int(3));
555 expected_map.insert("d".to_string(), Value::Int(4));
556 assert_eq!(map_val, Value::Map(expected_map));
557
558 assert_eq!(Value::from(Some(42i64)), Value::Int(42));
560 assert_eq!(Value::from(None::<i64>), Value::Null);
561 }
562
563 #[test]
564 fn test_default() {
565 assert_eq!(Value::default(), Value::Null);
566 }
567
568 #[test]
569 fn test_mutable_accessors() {
570 let mut list_val = Value::List(vec![Value::Int(1), Value::Int(2)]);
572 if let Some(list) = list_val.as_list_mut() {
573 list.push(Value::Int(3));
574 list[0] = Value::Int(10);
575 }
576 assert_eq!(
577 list_val,
578 Value::List(vec![Value::Int(10), Value::Int(2), Value::Int(3)])
579 );
580
581 let mut int_val = Value::Int(42);
583 assert_eq!(int_val.as_list_mut(), None);
584
585 let mut map_val = Value::Map(BTreeMap::new());
587 if let Some(map) = map_val.as_map_mut() {
588 map.insert("key".to_string(), Value::Int(42));
589 if let Some(value) = map.get_mut("key") {
590 *value = Value::Int(99);
591 }
592 }
593 let mut expected = BTreeMap::new();
594 expected.insert("key".to_string(), Value::Int(99));
595 assert_eq!(map_val, Value::Map(expected));
596
597 assert_eq!(int_val.as_map_mut(), None);
599 }
600
601 #[test]
602 fn test_take() {
603 let mut value = Value::Int(42);
604 let taken = value.take();
605 assert_eq!(taken, Value::Int(42));
606 assert_eq!(value, Value::Null);
607
608 let mut list = Value::List(vec![Value::Int(1), Value::Int(2)]);
609 let taken = list.take();
610 assert_eq!(taken, Value::List(vec![Value::Int(1), Value::Int(2)]));
611 assert_eq!(list, Value::Null);
612
613 let mut null = Value::Null;
615 let taken = null.take();
616 assert_eq!(taken, Value::Null);
617 assert_eq!(null, Value::Null);
618 }
619
620 #[test]
621 fn test_partial_eq_string() {
622 let string_val = Value::String("hello".to_string());
623 assert_eq!(string_val, "hello");
624 assert_eq!(string_val, "hello".to_string());
625 assert_ne!(string_val, "world");
626 }
627
628 #[test]
629 fn test_partial_eq_int() {
630 let int_val = Value::Int(42);
631 assert_eq!(int_val, 42i64);
632 assert_ne!(int_val, 43i64);
633 }
634
635 #[test]
636 fn test_partial_eq_float() {
637 let float_val = Value::Float(2.5);
638 assert_eq!(float_val, 2.5f64);
639 assert_ne!(float_val, 1.5f64);
640 }
641
642 #[test]
643 fn test_partial_eq_bool() {
644 let bool_val = Value::Bool(true);
645 assert_eq!(bool_val, true);
646 assert_ne!(bool_val, false);
647 }
648
649 #[test]
650 fn test_partial_eq_mismatched_types() {
651 let int_val = Value::Int(42);
652 let string_val = Value::String("hello".to_string());
653 assert_ne!(int_val, "42");
654 assert_ne!(string_val, 42i64);
655 }
656}