1#[derive(Debug, Clone, PartialEq, Default)]
23pub enum Value {
24 #[default]
26 Null,
27
28 Bool(bool),
30
31 String(String),
33
34 Integer(i64),
36
37 Float(f64),
39
40 Array(Vec<Value>),
42
43 Map(Vec<(String, Value)>),
45}
46
47impl Value {
48 pub fn null() -> Self {
59 Value::Null
60 }
61
62 pub fn bool(b: bool) -> Self {
73 Value::Bool(b)
74 }
75
76 pub fn string<S: Into<String>>(s: S) -> Self {
87 Value::String(s.into())
88 }
89
90 pub fn integer(i: i64) -> Self {
101 Value::Integer(i)
102 }
103
104 pub fn float(f: f64) -> Self {
115 Value::Float(f)
116 }
117
118 pub fn array(v: Vec<Value>) -> Self {
132 Value::Array(v)
133 }
134
135 pub fn map(m: Vec<(String, Value)>) -> Self {
148 Value::Map(m)
149 }
150
151 pub fn is_null(&self) -> bool {
165 matches!(self, Value::Null)
166 }
167
168 pub fn is_bool(&self) -> bool {
179 matches!(self, Value::Bool(_))
180 }
181
182 pub fn is_string(&self) -> bool {
193 matches!(self, Value::String(_))
194 }
195
196 pub fn is_number(&self) -> bool {
210 matches!(self, Value::Integer(_) | Value::Float(_))
211 }
212
213 pub fn is_integer(&self) -> bool {
224 matches!(self, Value::Integer(_))
225 }
226
227 pub fn is_float(&self) -> bool {
238 matches!(self, Value::Float(_))
239 }
240
241 pub fn is_array(&self) -> bool {
252 matches!(self, Value::Array(_))
253 }
254
255 pub fn is_map(&self) -> bool {
266 matches!(self, Value::Map(_))
267 }
268
269 pub fn as_bool(&self) -> Option<bool> {
280 match self {
281 Value::Bool(b) => Some(*b),
282 _ => None,
283 }
284 }
285
286 pub fn as_str(&self) -> Option<&str> {
297 match self {
298 Value::String(s) => Some(s),
299 _ => None,
300 }
301 }
302
303 pub fn as_integer(&self) -> Option<i64> {
314 match self {
315 Value::Integer(i) => Some(*i),
316 _ => None,
317 }
318 }
319
320 pub fn as_u16(&self) -> Option<u16> {
325 match self {
326 Value::Integer(i) => u16::try_from(*i).ok(),
327 _ => None,
328 }
329 }
330
331 pub fn to_u16(&self) -> Option<u16> {
336 match self {
337 Value::Integer(i) => u16::try_from(*i).ok(),
338 Value::String(s) => s.parse::<u16>().ok(),
339 _ => None,
340 }
341 }
342
343 pub fn as_u16_or(&self, default: u16) -> u16 {
345 self.to_u16().unwrap_or(default)
346 }
347 pub fn as_float(&self) -> Option<f64> {
358 match self {
359 Value::Float(f) => Some(*f),
360 _ => None,
361 }
362 }
363
364 pub fn as_array(&self) -> Option<&Vec<Value>> {
376 match self {
377 Value::Array(a) => Some(a),
378 _ => None,
379 }
380 }
381
382 pub fn as_map(&self) -> Option<&Vec<(String, Value)>> {
394 match self {
395 Value::Map(m) => Some(m),
396 _ => None,
397 }
398 }
399
400 pub fn len(&self) -> usize {
415 match self {
416 Value::Array(a) => a.len(),
417 Value::Map(m) => m.len(),
418 _ => 0,
419 }
420 }
421
422 pub fn is_empty(&self) -> bool {
433 match self {
434 Value::String(s) => s.is_empty(),
435 Value::Array(a) => a.is_empty(),
436 Value::Map(m) => m.is_empty(),
437 Value::Null => true,
438 _ => false,
439 }
440 }
441
442 pub fn to_string_repr(&self) -> String {
456 match self {
457 Value::Null => "null".to_string(),
458 Value::Bool(b) => b.to_string(),
459 Value::String(s) => s.clone(),
460 Value::Integer(i) => i.to_string(),
461 Value::Float(f) => f.to_string(),
462 Value::Array(a) => {
463 let mut items = Vec::with_capacity(a.len());
464 for v in a {
465 items.push(v.to_string_repr());
466 }
467 format!("[{}]", items.join(", "))
468 }
469 Value::Map(m) => {
470 let mut items = Vec::with_capacity(m.len());
471 for (k, v) in m {
472 items.push(format!("{}: {}", k, v.to_string_repr()));
473 }
474 format!("{{{}}}", items.join(", "))
475 }
476 }
477 }
478}
479
480impl From<bool> for Value {
481 fn from(b: bool) -> Self {
482 Value::Bool(b)
483 }
484}
485
486impl From<String> for Value {
487 fn from(s: String) -> Self {
488 Value::String(s)
489 }
490}
491
492impl From<&str> for Value {
493 fn from(s: &str) -> Self {
494 Value::String(s.to_string())
495 }
496}
497
498impl From<i8> for Value {
499 fn from(i: i8) -> Self {
500 Value::Integer(i as i64)
501 }
502}
503
504impl From<i16> for Value {
505 fn from(i: i16) -> Self {
506 Value::Integer(i as i64)
507 }
508}
509
510impl From<i32> for Value {
511 fn from(i: i32) -> Self {
512 Value::Integer(i as i64)
513 }
514}
515
516impl From<i64> for Value {
517 fn from(i: i64) -> Self {
518 Value::Integer(i)
519 }
520}
521
522impl From<isize> for Value {
523 fn from(i: isize) -> Self {
524 Value::Integer(i as i64)
525 }
526}
527
528impl From<u8> for Value {
529 fn from(i: u8) -> Self {
530 Value::Integer(i as i64)
531 }
532}
533
534impl From<u16> for Value {
535 fn from(i: u16) -> Self {
536 Value::Integer(i as i64)
537 }
538}
539
540impl From<u32> for Value {
541 fn from(i: u32) -> Self {
542 Value::Integer(i as i64)
543 }
544}
545
546impl From<u64> for Value {
547 #[allow(clippy::cast_precision_loss, clippy::cast_possible_truncation)]
548 fn from(i: u64) -> Self {
549 if i > i64::MAX as u64 {
551 Value::Float(i as f64)
552 } else {
553 Value::Integer(i as i64)
554 }
555 }
556}
557
558impl From<usize> for Value {
559 #[allow(clippy::cast_precision_loss, clippy::cast_possible_truncation)]
560 fn from(i: usize) -> Self {
561 if i > i64::MAX as usize {
563 Value::Float(i as f64)
564 } else {
565 Value::Integer(i as i64)
566 }
567 }
568}
569
570impl From<f32> for Value {
571 fn from(f: f32) -> Self {
572 Value::Float(f as f64)
573 }
574}
575
576impl From<f64> for Value {
577 fn from(f: f64) -> Self {
578 Value::Float(f)
579 }
580}
581
582impl<T> From<Vec<T>> for Value
583where
584 T: Into<Value>,
585{
586 fn from(v: Vec<T>) -> Self {
587 Value::Array(v.into_iter().map(|t| t.into()).collect())
588 }
589}
590
591impl<K, V> From<std::collections::HashMap<K, V>> for Value
592where
593 K: Into<String>,
594 V: Into<Value>,
595{
596 fn from(m: std::collections::HashMap<K, V>) -> Self {
597 Value::Map(m.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
598 }
599}
600
601#[cfg(test)]
602mod tests {
603 use super::*;
604
605 #[test]
606 fn test_value_null() {
607 let value = Value::null();
608 assert!(value.is_null());
609 assert!(!value.is_string());
610 }
611
612 #[test]
613 fn test_value_bool() {
614 let value = Value::bool(true);
615 assert!(value.is_bool());
616 assert_eq!(value.as_bool(), Some(true));
617 }
618
619 #[test]
620 fn test_value_string() {
621 let value = Value::string("hello");
622 assert!(value.is_string());
623 assert_eq!(value.as_str(), Some("hello"));
624 }
625
626 #[test]
627 fn test_value_integer() {
628 let value = Value::integer(42);
629 assert!(value.is_integer());
630 assert!(value.is_number());
631 assert_eq!(value.as_integer(), Some(42));
632 }
633
634 #[test]
635 fn test_value_float() {
636 let value = Value::float(3.14);
637 assert!(value.is_float());
638 assert!(value.is_number());
639 assert_eq!(value.as_float(), Some(3.14));
640 }
641
642 #[test]
643 fn test_value_array() {
644 let value = Value::array(vec![Value::integer(1), Value::integer(2)]);
645 assert!(value.is_array());
646 assert_eq!(value.len(), 2);
647 }
648
649 #[test]
650 fn test_value_map() {
651 let value = Value::map(vec![
652 ("key1".to_string(), Value::string("value1".to_string())),
653 ("key2".to_string(), Value::string("value2".to_string())),
654 ]);
655 assert!(value.is_map());
656 assert_eq!(value.len(), 2);
657 }
658
659 #[test]
660 fn test_value_len() {
661 let value = Value::array(vec![Value::integer(1)]);
662 assert_eq!(value.len(), 1);
663
664 let value = Value::string("test");
665 assert_eq!(value.len(), 0);
666 }
667
668 #[test]
669 fn test_value_is_empty() {
670 let value = Value::array(vec![]);
671 assert!(value.is_empty());
672
673 let value = Value::map(vec![]);
674 assert!(value.is_empty());
675 }
676
677 #[test]
678 fn test_value_to_string_repr() {
679 assert_eq!(Value::null().to_string_repr(), "null");
680 assert_eq!(Value::bool(true).to_string_repr(), "true");
681 assert_eq!(Value::string("hello").to_string_repr(), "hello");
682 assert_eq!(Value::integer(42).to_string_repr(), "42");
683 assert_eq!(Value::float(3.14).to_string_repr(), "3.14");
684 assert_eq!(
685 Value::array(vec![Value::integer(1), Value::integer(2)]).to_string_repr(),
686 "[1, 2]"
687 );
688 }
689
690 #[test]
691 fn test_value_from_bool() {
692 let value: Value = true.into();
693 assert!(value.is_bool());
694 }
695
696 #[test]
697 fn test_value_from_string() {
698 let value: Value = "hello".into();
699 assert!(value.is_string());
700 }
701
702 #[test]
703 fn test_value_from_integer() {
704 let value: Value = 42i32.into();
705 assert!(value.is_integer());
706 }
707
708 #[test]
709 fn test_value_from_float() {
710 let value: Value = 3.14f64.into();
711 assert!(value.is_float());
712 }
713
714 #[test]
715 fn test_value_from_vec() {
716 let value: Value = vec![1, 2, 3].into();
717 assert!(value.is_array());
718 assert_eq!(value.len(), 3);
719 }
720
721 #[test]
722 fn test_value_default() {
723 let value: Value = Default::default();
724 assert!(value.is_null());
725 }
726
727 #[test]
728 fn test_value_clone() {
729 let value1 = Value::string("test".to_string());
730 let value2 = value1.clone();
731 assert_eq!(value1, value2);
732 }
733
734 #[test]
735 fn test_value_partial_eq() {
736 assert_eq!(
737 Value::string("a".to_string()),
738 Value::string("a".to_string())
739 );
740 assert_ne!(
741 Value::string("a".to_string()),
742 Value::string("b".to_string())
743 );
744 }
745
746 #[test]
747 fn test_value_as_array_mut() {
748 let value = Value::array(vec![Value::integer(1)]);
749 let arr = value.as_array().expect("test should succeed");
750 assert_eq!(arr.len(), 1);
751 }
752
753 #[test]
754 fn test_value_as_map_mut() {
755 let value = Value::map(vec![(
756 "key".to_string(),
757 Value::string("value".to_string()),
758 )]);
759 let map = value.as_map().expect("test should succeed");
760 assert_eq!(map.len(), 1);
761 }
762
763 #[test]
764 fn test_value_factory_methods() {
765 assert!(Value::null().is_null());
766 assert!(Value::bool(true).is_bool());
767 assert!(Value::string("test").is_string());
768 assert!(Value::integer(42).is_integer());
769 assert!(Value::float(3.14).is_float());
770 assert!(Value::array(vec![]).is_array());
771 assert!(Value::map(vec![]).is_map());
772 }
773
774 #[test]
775 fn test_value_from_usize() {
776 let value: Value = 42usize.into();
777 assert_eq!(value.as_integer(), Some(42));
778 }
779
780 #[test]
781 fn test_value_from_u64() {
782 let value: Value = 42u64.into();
783 assert_eq!(value.as_integer(), Some(42));
784 }
785
786 #[test]
787 fn test_value_from_i8() {
788 let value: Value = (-42i8).into();
789 assert_eq!(value.as_integer(), Some(-42));
790 }
791
792 #[test]
793 fn test_value_from_f32() {
794 let value: Value = Value::from(3.14f32);
795 let f = value.as_float().expect("test should succeed");
796 assert!((f - 3.14f64).abs() < 1e-6);
797 }
798
799 #[test]
800 fn test_value_from_hashmap() {
801 use std::collections::HashMap;
802
803 let mut map = HashMap::new();
804 map.insert("key1", "value1");
805 map.insert("key2", "value2");
806
807 let value: Value = map.into();
808 assert!(value.is_map());
809 assert_eq!(value.len(), 2);
810 }
811 #[test]
812 fn test_value_u16_helpers() {
813 let i = Value::integer(8080);
814 assert_eq!(i.as_u16(), Some(8080));
815 assert_eq!(i.to_u16(), Some(8080));
816
817 let s = Value::string("65535");
818 assert_eq!(s.as_u16(), None);
819 assert_eq!(s.to_u16(), Some(65535));
820
821 let invalid = Value::integer(-1);
822 assert_eq!(invalid.as_u16(), None);
823 assert_eq!(invalid.as_u16_or(3000), 3000);
824 }
825}