valu3/
value.rs

1//! This module provides a `Value` enum to represent different data types and
2//! a trait `ToValueBehavior` to convert them to `Value`. The supported data types
3//! are: String, Number, Boolean, Array, Object, Null, Undefined, and DateTime.
4//!
5//! # Examples
6//!
7//! ```
8//! use crate::{Array, DateTime, Number, Object, StringB, Value};
9//!
10//! let string_value = Value::String(StringB::from("hello".to_string()));
11//! let number_value = Value::Number(Number::from(42));
12//! let boolean_value = Value::Boolean(true);
13//! let null_value = Value::Null;
14//! let undefined_value = Value::Undefined;
15//! let mut datetime_value = Value::DateTime(DateTime::from("2023-04-05T00:00:00Z"));
16//! ```
17use crate::prelude::*;
18use std::fmt::{Display, Formatter};
19
20/// Represents different data types as an enum.
21#[derive(Debug, Clone, PartialEq, PartialOrd)]
22pub enum Value {
23    String(StringB),
24    Number(Number),
25    Boolean(bool),
26    Array(Array),
27    Object(Object),
28    Null,
29    Undefined,
30    DateTime(DateTime),
31}
32
33impl Default for Value {
34    fn default() -> Self {
35        Value::Null
36    }
37}
38
39impl ValueTrait for Value {}
40
41impl Display for Value {
42    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
43        match self {
44            Value::String(value) => write!(f, "{}", value.as_string()),
45            Value::Number(value) => write!(f, "{}", value),
46            Value::Boolean(value) => write!(f, "{}", if *value { "true" } else { "false" }),
47            Value::Array(_) => write!(f, "{}", self.to_json(JsonMode::Indented)),
48            Value::Object(_) => write!(f, "{}", self.to_json(JsonMode::Indented)),
49            Value::Null => write!(f, "null"),
50            Value::Undefined => write!(f, "undefined"),
51            Value::DateTime(value) => write!(f, "{}", value),
52        }
53    }
54}
55
56#[cfg(test)]
57mod tests {
58    use crate::prelude::*;
59
60    // Tests for the different data types and their conversion to a `Value` enum.
61    #[test]
62    fn test_value_string() {
63        let string = StringB::from("hello".to_string());
64        let value = Value::String(string.clone());
65        assert_eq!(value, Value::String(string));
66    }
67
68    #[test]
69    fn test_value_display_string() {
70        let string = StringB::from("hello".to_string());
71        let value = Value::String(string.clone());
72        assert_eq!(format!("{}", value), format!("hello"));
73    }
74
75    #[test]
76    fn test_value_number() {
77        let number = Number::from(42);
78        let value = Value::Number(number);
79        assert_eq!(value, Value::Number(Number::from(42)));
80    }
81
82    #[test]
83    fn test_value_boolean() {
84        let value = Value::Boolean(true);
85        assert_eq!(value, Value::Boolean(true));
86    }
87
88    #[test]
89    fn test_value_array() {
90        let mut array = Array::new();
91        array.push(Value::Number(Number::from(1)));
92        array.push(Value::Number(Number::from(2)));
93        let value = Value::Array(array.clone());
94        assert_eq!(value, Value::Array(array));
95    }
96
97    #[test]
98    fn test_value_object() {
99        let mut object = Object::default();
100        object.insert(
101            "key".to_string(),
102            Value::String(StringB::from("value".to_string())),
103        );
104        let value = Value::Object(object.clone());
105        assert_eq!(value, Value::Object(object));
106    }
107
108    #[test]
109    fn test_value_null() {
110        let value = Value::Null;
111        assert_eq!(value, Value::Null);
112    }
113
114    #[test]
115    fn test_value_undefined() {
116        let value = Value::Undefined;
117        assert_eq!(value, Value::Undefined);
118    }
119
120    #[test]
121    fn test_value_datetime() {
122        let datetime = DateTime::from("2023-04-05T00:00:00Z");
123        let value = Value::DateTime(datetime.clone());
124        assert_eq!(value, Value::DateTime(datetime));
125    }
126
127    #[test]
128    fn test_partial_eq() {
129        let value1 = Value::String(StringB::from("hello".to_string()));
130        let value2 = Value::String(StringB::from("hello".to_string()));
131        assert!(value1 == value2);
132    }
133
134    #[test]
135    fn test_partial_ord() {
136        let value1 = Value::Number(Number::from(3.14));
137        let value2 = Value::Number(Number::from(3.141));
138        assert!(value1 < value2);
139        assert!(value2 > value1);
140        assert_eq!(value1 >= value2, false);
141        assert_eq!(value2 <= value1, false);
142    }
143}