1use std::{collections::BTreeMap, fmt::Display, hash::Hash};
2
3use possibly::possibly;
4use serde::de::{Expected, Unexpected};
5
6#[derive(Debug, Clone, PartialEq)]
7pub enum Value {
8 Unsigned(u64),
9 Signed(i64),
10 Float(f64),
11 Object(BTreeMap<String, Value>),
12 String(String),
13 Bool(bool),
14 Array(Vec<Value>),
15 Null,
16}
17
18impl Hash for Value {
19 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
20 match self {
21 Self::Array(arr) => arr.hash(state),
22 Self::Object(obj) => obj.hash(state),
23 Self::Bool(b) => b.hash(state),
24 Self::Float(f) => {
25 if f.is_finite() {
26 f.to_bits().hash(state);
27 } else {
28 panic!("non finite floats are not supported for hashing")
29 }
30 }
31 Self::Unsigned(i) => i.hash(state),
32 Self::Signed(i) => i.hash(state),
33 Self::Null => std::mem::discriminant(self).hash(state),
34 Self::String(s) => s.hash(state),
35 }
36 }
37}
38
39impl Default for Value {
40 fn default() -> Self {
41 Self::Null
42 }
43}
44
45impl AsRef<Value> for Value {
46 fn as_ref(&self) -> &Value {
47 self
48 }
49}
50
51impl Value {
52 pub fn string<S: AsRef<str>>(str: S) -> Value {
53 Self::String(str.as_ref().to_owned())
54 }
55
56 pub fn float(f: f64) -> Value {
57 Self::Float(f)
58 }
59
60 pub fn object<S: AsRef<str>, V: Into<Value>, A: IntoIterator<Item = (S, V)>>(
61 mapping: A,
62 ) -> Value {
63 Self::Object(
64 mapping
65 .into_iter()
66 .map(|(k, v)| (k.as_ref().to_owned(), v.into()))
67 .collect(),
68 )
69 }
70
71 pub fn array<V: Into<Value>, A: IntoIterator<Item = V>>(elements: A) -> Value {
72 Self::Array(elements.into_iter().map(V::into).collect())
73 }
74
75 pub fn signed(i: i64) -> Value {
76 Self::Signed(i)
77 }
78
79 pub fn unsigned(i: u64) -> Value {
80 Self::Unsigned(i)
81 }
82
83 pub fn bool(b: bool) -> Value {
84 Self::Bool(b)
85 }
86
87 pub fn as_signed(&self) -> Option<i64> {
88 possibly!(self, Self::Signed(i) => *i)
89 }
90
91 pub fn as_unsigned(&self) -> Option<u64> {
92 possibly!(self, Self::Unsigned(i) => *i)
93 }
94
95 pub fn as_float(&self) -> Option<f64> {
96 possibly!(self, Self::Float(f) => *f)
97 }
98
99 pub fn as_object(&self) -> Option<BTreeMap<&str, &Value>> {
100 possibly!(self, Self::Object(obj) => obj.iter()
101 .map(|(key, value)| (key.as_str(), value))
102 .collect()
103 )
104 }
105
106 pub fn as_mut_object(&mut self) -> Option<BTreeMap<&str, &mut Value>> {
107 possibly!(self, Self::Object(obj) => obj.iter_mut()
108 .map(|(key, value)| (key.as_str(), value))
109 .collect()
110 )
111 }
112
113 pub fn as_vec(&self) -> Option<&[Value]> {
114 possibly!(self, Self::Array(vec) => vec.as_slice())
115 }
116
117 pub fn as_vec_and_then<T, C: FnMut(&Value) -> Option<T>>(&self, mapper: C) -> Option<Vec<T>> {
118 self.as_vec()
119 .and_then(|vec| vec.iter().map(mapper).collect())
120 }
121
122 pub fn as_object_and_then<T, C: Fn(&Value) -> Option<T>>(
123 &self,
124 mapper: C,
125 ) -> Option<BTreeMap<String, T>> {
126 match self {
127 Self::Object(object) => object
128 .iter()
129 .map(|(name, value)| {
130 mapper(value).map(|mapped_value| (name.to_owned(), mapped_value))
131 })
132 .collect(),
133 _ => None,
134 }
135 }
136
137 pub fn as_mut_vec(&mut self) -> Option<&mut [Value]> {
138 possibly!(self, Self::Array(vec) => vec.as_mut_slice())
139 }
140
141 pub fn as_str(&self) -> Option<&str> {
142 possibly!(self, Self::String(s) => s)
143 }
144
145 pub fn as_bool(&self) -> Option<bool> {
146 match self {
147 Self::Bool(bool) => Some(*bool),
148 _ => None,
149 }
150 }
151
152 pub fn is_null(&self) -> bool {
153 matches!(self, Self::Null)
154 }
155
156 pub fn at<S: AsRef<str>>(&self, path: S) -> Option<&Self> {
158 if let Self::Object(obj) = self {
159 match path.as_ref().split_once('.') {
160 Some((curr, rest)) => obj.get(curr).and_then(|next| next.at(rest)),
161 None => obj.get(path.as_ref()),
162 }
163 } else {
164 None
165 }
166 }
167
168 pub fn overwrite<V: AsRef<Value>>(&mut self, source: V) {
170 match (source.as_ref(), self) {
171 (Value::Object(src), Value::Object(dst)) => {
172 for (key, val) in src {
173 if let Some(existing) = dst.get_mut(key) {
174 existing.overwrite(val);
175 } else {
176 let _ = dst.insert(key.clone(), val.clone());
177 }
178 }
179 }
180 (source, target) => {
181 let _ = std::mem::replace(target, source.clone());
182 }
183 }
184 }
185
186 pub(crate) fn invalid_type<E>(&self, exp: &dyn Expected) -> E
187 where
188 E: serde::de::Error,
189 {
190 serde::de::Error::invalid_type(self.unexpected(), exp)
191 }
192
193 pub(crate) fn unexpected(&self) -> Unexpected {
194 match self {
195 Value::Null => Unexpected::Unit,
196 Value::Bool(b) => Unexpected::Bool(*b),
197 Value::Unsigned(i) => Unexpected::Unsigned(*i),
198 Value::Signed(i) => Unexpected::Signed(*i),
199 Value::Float(f) => Unexpected::Float(*f),
200 Value::String(s) => Unexpected::Str(s),
201 Value::Array(_) => Unexpected::Seq,
202 Value::Object(_) => Unexpected::Map,
203 }
204 }
205}
206
207impl From<i8> for Value {
208 fn from(i: i8) -> Self {
209 Self::Signed(i as i64)
210 }
211}
212
213impl From<i16> for Value {
214 fn from(i: i16) -> Self {
215 Self::Signed(i as i64)
216 }
217}
218
219impl From<i32> for Value {
220 fn from(i: i32) -> Self {
221 Self::Signed(i as i64)
222 }
223}
224
225impl From<i64> for Value {
226 fn from(i: i64) -> Self {
227 Self::Signed(i)
228 }
229}
230
231impl From<u8> for Value {
232 fn from(i: u8) -> Self {
233 Self::Unsigned(i as u64)
234 }
235}
236
237impl From<u16> for Value {
238 fn from(i: u16) -> Self {
239 Self::Unsigned(i as u64)
240 }
241}
242
243impl From<u32> for Value {
244 fn from(i: u32) -> Self {
245 Self::Unsigned(i as u64)
246 }
247}
248
249impl From<u64> for Value {
250 fn from(i: u64) -> Self {
251 Self::Unsigned(i)
252 }
253}
254
255impl From<f32> for Value {
256 fn from(f: f32) -> Self {
257 Self::Float(f as f64)
258 }
259}
260
261impl From<f64> for Value {
262 fn from(f: f64) -> Self {
263 Self::Float(f)
264 }
265}
266
267impl From<bool> for Value {
268 fn from(b: bool) -> Self {
269 Self::Bool(b)
270 }
271}
272
273impl From<&str> for Value {
274 fn from(s: &str) -> Self {
275 Self::String(s.to_string())
276 }
277}
278
279impl From<String> for Value {
280 fn from(s: String) -> Self {
281 Self::String(s)
282 }
283}
284
285impl From<Vec<Value>> for Value {
286 fn from(vec: Vec<Value>) -> Self {
287 Self::Array(vec)
288 }
289}
290
291impl From<()> for Value {
292 fn from(_: ()) -> Self {
293 Self::Null
294 }
295}
296
297impl Display for Value {
298 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
299 match self {
300 Self::Bool(bool) => f.write_str(&bool.to_string()),
301 Self::Null => f.write_str("null"),
302 Self::String(str) => write!(
303 f,
304 "\"{}\"",
305 str.replace('\n', "\\n")
306 .replace('\r', "\\r")
307 .replace('\t', "\\t")
308 ),
309 Self::Array(arr) => write!(
310 f,
311 "[{}]",
312 arr.iter()
313 .map(|v| v.to_string())
314 .collect::<Vec<String>>()
315 .join(", ")
316 ),
317 Self::Object(obj) => write!(
318 f,
319 "{{{}}}",
320 obj.iter()
321 .map(|(key, val)| format!("\"{key}\": {}", val))
322 .collect::<Vec<String>>()
323 .join(", ")
324 ),
325 Self::Float(i) => f.write_str(i.to_string().as_str()),
326 Self::Unsigned(i) => f.write_str(i.to_string().as_str()),
327 Self::Signed(i) => f.write_str(i.to_string().as_str()),
328 }
329 }
330}