1use crate::array::Array;
2use crate::error::Error;
3use crate::object::Object;
4use crate::serde::{from_value, to_value};
5use std::fmt::Display;
6use std::hash::{Hash, Hasher};
7use std::str::FromStr;
8
9#[derive(Clone, Copy, Debug)]
11pub enum Number {
12 Decimal(f64),
13 Integer(i128),
14}
15
16#[derive(Clone, Debug, Eq)]
18pub enum Value {
19 Array(Array),
20 Bool(bool),
21 Null,
22 Number(Number),
23 Object(Object),
24 String(String),
25}
26
27impl Eq for Number {}
28
29impl Hash for Number {
30 fn hash<H: Hasher>(&self, state: &mut H) {
31 match self {
32 Number::Decimal(v) => v.to_string().hash(state),
33 Number::Integer(v) => state.write_i128(*v),
34 }
35 }
36}
37
38impl PartialEq for Number {
39 fn eq(&self, other: &Self) -> bool {
40 match (self, other) {
41 (Number::Decimal(s), Number::Decimal(o)) => s == o,
42 (Number::Integer(s), Number::Integer(o)) => s == o,
43 _ => false,
44 }
45 }
46}
47
48impl Number {
49 pub fn as_decimal(&self) -> Option<f64> {
50 match self {
51 Number::Decimal(v) => Some(*v),
52 Number::Integer(_) => None,
53 }
54 }
55
56 pub fn as_integer(&self) -> Option<i128> {
57 match self {
58 Number::Decimal(_) => None,
59 Number::Integer(v) => Some(*v),
60 }
61 }
62
63 pub fn is_decimal(&self) -> bool {
64 matches!(self, Number::Decimal(_))
65 }
66
67 pub fn is_integer(&self) -> bool {
68 matches!(self, Number::Integer(_))
69 }
70}
71
72impl PartialEq for Value {
73 fn eq(&self, other: &Self) -> bool {
74 match self {
75 Value::Array(v) => Some(v) == other.as_array().as_ref(),
76 Value::Bool(v) => Some(v) == other.as_bool().as_ref(),
77 Value::Null => other.is_null(),
78 Value::Number(v) => Some(v) == other.as_number().as_ref(),
79 Value::Object(v) => Some(v) == other.as_object().as_ref(),
80 Value::String(v) => Some(v) == other.as_string().as_ref(),
81 }
82 }
83}
84
85impl Display for Value {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 write!(
88 f,
89 "{}",
90 to_value(self).map_or("".to_string(), |v| v.to_string())
91 )
92 }
93}
94
95impl FromStr for Value {
96 type Err = Error;
97
98 fn from_str(s: &str) -> Result<Self, Self::Err> {
99 let v: serde_json::Value = serde_json::from_str(s)?;
100
101 match from_value(&v) {
102 Some(c) => Ok(c),
103 None => Err(Error::ConvertFrom),
104 }
105 }
106}
107
108impl Hash for Value {
109 fn hash<H: Hasher>(&self, state: &mut H) {
110 match self {
111 Value::Array(v) => v.hash(state),
112 Value::Bool(v) => v.hash(state),
113 Value::Null => state.write_u8(0),
114 Value::Number(v) => v.hash(state),
115 Value::Object(v) => v.hash(state),
116 Value::String(v) => v.hash(state),
117 }
118 }
119}
120
121impl TryFrom<serde_json::Value> for Value {
122 type Error = Error;
123
124 fn try_from(value: serde_json::Value) -> Result<Self, Self::Error> {
125 match from_value(&value) {
126 Some(v) => Ok(v),
127 None => Err(Error::ConvertFrom),
128 }
129 }
130}
131
132impl TryFrom<Value> for serde_json::Value {
133 type Error = Error;
134
135 fn try_from(value: Value) -> Result<Self, Self::Error> {
136 match to_value(&value) {
137 Some(v) => Ok(v),
138 None => Err(Error::ConvertTo),
139 }
140 }
141}
142
143impl Value {
144 pub fn as_array(&self) -> Option<Array> {
145 match self {
146 Self::Array(a) => Some(a.clone()),
147 _ => None,
148 }
149 }
150
151 pub fn as_bool(&self) -> Option<bool> {
152 match self {
153 Self::Bool(b) => Some(*b),
154 _ => None,
155 }
156 }
157
158 pub fn as_decimal(&self) -> Option<f64> {
159 match self {
160 Self::Number(n) => Number::as_decimal(n),
161 _ => None,
162 }
163 }
164
165 pub fn as_integer(&self) -> Option<i128> {
166 match self {
167 Self::Number(n) => Number::as_integer(n),
168 _ => None,
169 }
170 }
171
172 pub fn as_number(&self) -> Option<Number> {
173 match self {
174 Self::Number(n) => Some(n.clone()),
175 _ => None,
176 }
177 }
178
179 pub fn as_object(&self) -> Option<Object> {
180 match self {
181 Self::Object(o) => Some(o.clone()),
182 _ => None,
183 }
184 }
185
186 pub fn as_string(&self) -> Option<String> {
187 match self {
188 Self::String(s) => Some(s.clone()),
189 _ => None,
190 }
191 }
192
193 pub fn is_array(&self) -> bool {
194 matches!(self, Self::Array(_))
195 }
196
197 pub fn is_bool(&self) -> bool {
198 matches!(self, Self::Bool(_))
199 }
200
201 pub fn is_decimal(&self) -> bool {
202 match self {
203 Self::Number(n) => Number::is_decimal(n),
204 _ => false,
205 }
206 }
207
208 pub fn is_integer(&self) -> bool {
209 match self {
210 Self::Number(n) => Number::is_integer(n),
211 _ => false,
212 }
213 }
214
215 pub fn is_null(&self) -> bool {
216 matches!(self, Self::Null)
217 }
218
219 pub fn is_number(&self) -> bool {
220 matches!(self, Self::Number(_))
221 }
222
223 pub fn is_object(&self) -> bool {
224 matches!(self, Self::Object(_))
225 }
226
227 pub fn is_scalar(&self) -> bool {
228 self.is_null() || self.is_bool() || self.is_number() || self.is_string()
229 }
230
231 pub fn is_string(&self) -> bool {
232 matches!(self, Self::String(_))
233 }
234
235 pub fn is_structure(&self) -> bool {
236 self.is_array() || self.is_object()
237 }
238}