1use crate::json::index::Index;
2use crate::json::key::Key;
3use crate::json::num::{N, Number};
4pub use crate::json::object_vec::ObjectAsVec;
5use core::fmt;
6use core::hash::Hash;
7use std::borrow::Cow;
8use std::fmt::{Debug, Display};
9use std::str::FromStr;
10
11#[derive(Clone, Eq, PartialEq, Hash, Default)]
13pub enum Value<'ctx, P: Property, E: Element> {
14 #[default]
15 Null,
16 Bool(bool),
17 Number(Number),
18 Element(E),
19 Str(Cow<'ctx, str>),
20 Array(Vec<Value<'ctx, P, E>>),
21 Object(ObjectAsVec<'ctx, P, E>),
22}
23
24pub trait Property: Debug + Clone + PartialEq + Eq + PartialOrd + Ord + Hash {
25 fn try_parse(key: Option<&Key<'_, Self>>, value: &str) -> Option<Self>;
26 fn to_cow(&self) -> Cow<'static, str>;
27}
28
29pub trait Element: Clone + PartialEq + Eq + Hash + Debug + Sized {
30 type Property: Property;
31
32 fn try_parse<P>(key: &Key<'_, Self::Property>, value: &str) -> Option<Self>;
33 fn to_cow(&self) -> Cow<'_, str>;
34}
35
36impl<'ctx, P: Property, E: Element<Property = P>> Value<'ctx, P, E> {
37 pub fn new_boolean_set(set: impl IntoIterator<Item = (Key<'ctx, P>, bool)>) -> Self {
38 let mut obj = Vec::new();
39 for (key, value) in set {
40 obj.push((key, value.into()));
41 }
42 Value::Object(obj.into())
43 }
44
45 pub fn parse_json(json: &'ctx str) -> Result<Self, String> {
46 serde_json::from_str(json).map_err(|e| e.to_string())
47 }
48
49 #[inline]
51 pub fn get<I: Index<'ctx, P, E>>(&'ctx self, index: I) -> &'ctx Value<'ctx, P, E> {
52 index.index_into(self).unwrap_or(&Value::Null)
53 }
54
55 pub fn is_object_and_contains_key(&self, key: &Key<'_, P>) -> bool {
56 match self {
57 Value::Object(obj) => obj.contains_key(key),
58 _ => false,
59 }
60 }
61
62 pub fn is_object_and_contains_any_key(&self, keys: &[Key<'_, P>]) -> bool {
63 match self {
64 Value::Object(obj) => obj.contains_any_key(keys),
65 _ => false,
66 }
67 }
68
69 pub fn is_null(&self) -> bool {
71 matches!(self, Value::Null)
72 }
73
74 pub fn is_array(&self) -> bool {
76 matches!(self, Value::Array(_))
77 }
78
79 pub fn is_object(&self) -> bool {
81 matches!(self, Value::Object(_))
82 }
83
84 pub fn is_bool(&self) -> bool {
86 matches!(self, Value::Bool(_))
87 }
88
89 pub fn is_number(&self) -> bool {
91 matches!(self, Value::Number(_))
92 }
93
94 pub fn is_string(&self) -> bool {
96 matches!(self, Value::Str(_))
97 }
98
99 pub fn is_i64(&self) -> bool {
103 match self {
104 Value::Number(n) => n.is_i64(),
105 _ => false,
106 }
107 }
108
109 pub fn is_u64(&self) -> bool {
113 match self {
114 Value::Number(n) => n.is_u64(),
115 _ => false,
116 }
117 }
118
119 pub fn is_f64(&self) -> bool {
121 match self {
122 Value::Number(n) => n.is_f64(),
123 _ => false,
124 }
125 }
126
127 pub fn iter_array(&self) -> Option<impl Iterator<Item = &Value<'_, P, E>>> {
129 match self {
130 Value::Array(arr) => Some(arr.iter()),
131 _ => None,
132 }
133 }
134
135 pub fn iter_object(&self) -> Option<impl Iterator<Item = (&Key<'_, P>, &Value<'_, P, E>)>> {
137 match self {
138 Value::Object(arr) => Some(arr.iter()),
139 _ => None,
140 }
141 }
142
143 pub fn as_array(&self) -> Option<&[Value<'ctx, P, E>]> {
145 match self {
146 Value::Array(arr) => Some(arr),
147 _ => None,
148 }
149 }
150
151 pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value<'ctx, P, E>>> {
152 match self {
153 Value::Array(arr) => Some(arr),
154 _ => None,
155 }
156 }
157
158 pub fn into_array(self) -> Option<Vec<Value<'ctx, P, E>>> {
159 match self {
160 Value::Array(arr) => Some(arr),
161 _ => None,
162 }
163 }
164
165 pub fn as_object(&self) -> Option<&ObjectAsVec<'ctx, P, E>> {
167 match self {
168 Value::Object(obj) => Some(obj),
169 _ => None,
170 }
171 }
172
173 pub fn as_object_mut(&mut self) -> Option<&mut ObjectAsVec<'ctx, P, E>> {
174 match self {
175 Value::Object(obj) => Some(obj),
176 _ => None,
177 }
178 }
179
180 pub fn into_object(self) -> Option<ObjectAsVec<'ctx, P, E>> {
181 match self {
182 Value::Object(obj) => Some(obj),
183 _ => None,
184 }
185 }
186
187 pub fn into_owned(self) -> Value<'static, P, E> {
188 match self {
189 Value::Null => Value::Null,
190 Value::Bool(b) => Value::Bool(b),
191 Value::Number(n) => Value::Number(n),
192 Value::Element(e) => Value::Element(e),
193 Value::Str(s) => Value::Str(Cow::Owned(s.into_owned())),
194 Value::Array(arr) => {
195 let owned_arr: Vec<Value<'static, P, E>> =
196 arr.into_iter().map(|v| v.into_owned()).collect();
197 Value::Array(owned_arr)
198 }
199 Value::Object(obj) => Value::Object(
200 obj.into_vec()
201 .into_iter()
202 .map(|(k, v)| (k.into_owned(), v.into_owned()))
203 .collect(),
204 ),
205 }
206 }
207
208 pub fn into_expanded_object(self) -> impl Iterator<Item = (Key<'ctx, P>, Value<'ctx, P, E>)> {
209 self.into_object()
210 .map(|obj| obj.into_vec())
211 .unwrap_or_default()
212 .into_iter()
213 }
214
215 pub fn into_expanded_boolean_set(self) -> impl Iterator<Item = (Key<'ctx, P>, bool)> {
216 self.into_object()
217 .map(|obj| obj.into_vec())
218 .unwrap_or_default()
219 .into_iter()
220 .filter_map(|(key, value)| value.as_bool().map(|b| (key, b)))
221 }
222
223 pub fn into_element(self) -> Option<E> {
224 match self {
225 Value::Element(element) => Some(element),
226 _ => None,
227 }
228 }
229
230 pub fn as_bool(&self) -> Option<bool> {
232 match self {
233 Value::Bool(b) => Some(*b),
234 _ => None,
235 }
236 }
237
238 pub fn as_str(&self) -> Option<Cow<'_, str>> {
240 match self {
241 Value::Str(text) => Some(text.as_ref().into()),
242 Value::Element(element) => Some(element.to_cow()),
243 _ => None,
244 }
245 }
246
247 pub fn into_string(self) -> Option<String> {
248 match self {
249 Value::Str(text) => Some(text.into_owned()),
250 Value::Element(element) => Some(element.to_cow().into_owned()),
251 _ => None,
252 }
253 }
254
255 pub fn as_i64(&self) -> Option<i64> {
257 match self {
258 Value::Number(n) => n.as_i64(),
259 _ => None,
260 }
261 }
262
263 pub fn as_u64(&self) -> Option<u64> {
265 match self {
266 Value::Number(n) => n.as_u64(),
267 _ => None,
268 }
269 }
270
271 pub fn as_f64(&self) -> Option<f64> {
273 match self {
274 Value::Number(n) => n.as_f64(),
275 _ => None,
276 }
277 }
278}
279
280impl<P: Property, E: Element> From<bool> for Value<'_, P, E> {
281 fn from(val: bool) -> Self {
282 Value::Bool(val)
283 }
284}
285
286impl<'a, P: Property, E: Element> From<&'a str> for Value<'a, P, E> {
287 fn from(val: &'a str) -> Self {
288 Value::Str(Cow::Borrowed(val))
289 }
290}
291
292impl<P: Property, E: Element> From<String> for Value<'_, P, E> {
293 fn from(val: String) -> Self {
294 Value::Str(Cow::Owned(val))
295 }
296}
297
298impl<'x, P: Property, E: Element> From<Cow<'x, str>> for Value<'x, P, E> {
299 fn from(val: Cow<'x, str>) -> Self {
300 Value::Str(val)
301 }
302}
303
304impl<'a, P: Property, E: Element, T: Into<Value<'a, P, E>>> From<Vec<T>> for Value<'a, P, E> {
305 fn from(val: Vec<T>) -> Self {
306 Value::Array(val.into_iter().map(Into::into).collect())
307 }
308}
309
310impl<'a, P: Property, E: Element, T: Clone + Into<Value<'a, P, E>>> From<&[T]> for Value<'a, P, E> {
311 fn from(val: &[T]) -> Self {
312 Value::Array(val.iter().map(Clone::clone).map(Into::into).collect())
313 }
314}
315
316impl<P: Property, E: Element> Debug for Value<'_, P, E> {
317 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
318 match self {
319 Value::Null => formatter.write_str("Null"),
320 Value::Bool(boolean) => write!(formatter, "Bool({})", boolean),
321 Value::Number(number) => match number.n {
322 N::PosInt(n) => write!(formatter, "Number({:?})", n),
323 N::NegInt(n) => write!(formatter, "Number({:?})", n),
324 N::Float(n) => write!(formatter, "Number({:?})", n),
325 },
326 Value::Str(string) => write!(formatter, "Str({:?})", string),
327 Value::Array(vec) => {
328 formatter.write_str("Array ")?;
329 Debug::fmt(vec, formatter)
330 }
331 Value::Object(map) => {
332 formatter.write_str("Object ")?;
333 Debug::fmt(map, formatter)
334 }
335 Value::Element(element) => write!(formatter, "Element({})", element.to_cow()),
336 }
337 }
338}
339
340impl<P: Property, E: Element> Display for Value<'_, P, E> {
342 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
343 write!(f, "{}", serde_json::Value::from(self.clone()))
344 }
345}
346
347impl<P: Property, E: Element> From<u64> for Value<'_, P, E> {
348 fn from(val: u64) -> Self {
349 Value::Number(val.into())
350 }
351}
352
353impl<P: Property, E: Element> From<i64> for Value<'_, P, E> {
354 fn from(val: i64) -> Self {
355 Value::Number(val.into())
356 }
357}
358
359impl<P: Property, E: Element> From<f64> for Value<'_, P, E> {
360 fn from(val: f64) -> Self {
361 Value::Number(val.into())
362 }
363}
364
365impl<P: Property, E: Element> From<Value<'_, P, E>> for serde_json::Value {
366 fn from(val: Value<'_, P, E>) -> Self {
367 match val {
368 Value::Null => serde_json::Value::Null,
369 Value::Bool(val) => serde_json::Value::Bool(val),
370 Value::Number(val) => serde_json::Value::Number(val.into()),
371 Value::Str(val) => serde_json::Value::String(val.to_string()),
372 Value::Array(vals) => {
373 serde_json::Value::Array(vals.into_iter().map(|val| val.into()).collect())
374 }
375 Value::Object(vals) => serde_json::Value::Object(vals.into()),
376 Value::Element(element) => serde_json::Value::String(element.to_cow().to_string()),
377 }
378 }
379}
380
381impl<P: Property, E: Element> From<&Value<'_, P, E>> for serde_json::Value {
382 fn from(val: &Value<'_, P, E>) -> Self {
383 match val {
384 Value::Null => serde_json::Value::Null,
385 Value::Bool(val) => serde_json::Value::Bool(*val),
386 Value::Number(val) => serde_json::Value::Number((*val).into()),
387 Value::Str(val) => serde_json::Value::String(val.to_string()),
388 Value::Array(vals) => {
389 serde_json::Value::Array(vals.iter().map(|val| val.into()).collect())
390 }
391 Value::Object(vals) => serde_json::Value::Object(vals.into()),
392 Value::Element(element) => serde_json::Value::String(element.to_cow().to_string()),
393 }
394 }
395}
396
397impl<'ctx, P: Property, E: Element> From<&'ctx serde_json::Value> for Value<'ctx, P, E> {
398 fn from(value: &'ctx serde_json::Value) -> Self {
399 match value {
400 serde_json::Value::Null => Value::Null,
401 serde_json::Value::Bool(b) => Value::Bool(*b),
402 serde_json::Value::Number(n) => {
403 if let Some(n) = n.as_i64() {
404 Value::Number(n.into())
405 } else if let Some(n) = n.as_u64() {
406 Value::Number(n.into())
407 } else if let Some(n) = n.as_f64() {
408 Value::Number(n.into())
409 } else {
410 unreachable!()
411 }
412 }
413 serde_json::Value::String(val) => Value::Str(Cow::Borrowed(val)),
414 serde_json::Value::Array(arr) => {
415 let out: Vec<Value<'ctx, P, E>> = arr.iter().map(|v| v.into()).collect();
416 Value::Array(out)
417 }
418 serde_json::Value::Object(obj) => {
419 let mut ans = ObjectAsVec(Vec::with_capacity(obj.len()));
420 for (k, v) in obj {
421 ans.insert(Key::Borrowed(k.as_str()), v.into());
422 }
423 Value::Object(ans)
424 }
425 }
426 }
427}
428
429#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
430pub struct Null;
431
432impl Display for Null {
433 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
434 write!(f, "null")
435 }
436}
437
438impl AsRef<str> for Null {
439 fn as_ref(&self) -> &str {
440 "null"
441 }
442}
443
444impl FromStr for Null {
445 type Err = ();
446
447 fn from_str(_: &str) -> Result<Self, Self::Err> {
448 Err(())
449 }
450}
451
452impl Property for Null {
453 fn try_parse(_: Option<&Key<'_, Self>>, _: &str) -> Option<Self> {
454 None
455 }
456
457 fn to_cow(&self) -> Cow<'static, str> {
458 "".into()
459 }
460}
461
462impl Element for Null {
463 type Property = Null;
464
465 fn try_parse<P>(_: &Key<'_, Self::Property>, _: &str) -> Option<Self> {
466 None
467 }
468
469 fn to_cow(&self) -> Cow<'_, str> {
470 "".into()
471 }
472}
473
474#[cfg(test)]
475mod tests {
476 use std::io;
477
478 use super::*;
479
480 #[test]
481 fn from_serde() {
482 let value = &serde_json::json!({
483 "a": 1,
484 "b": "2",
485 "c": [3, 4],
486 "d": {"e": "alo"}
487 });
488
489 let value: Value<'_, Null, Null> = value.into();
490 assert_eq!(value.get("a"), &Value::Number(1i64.into()));
491 assert_eq!(value.get("b"), &Value::Str("2".into()));
492 assert_eq!(value.get("c").get(0), &Value::Number(3i64.into()));
493 assert_eq!(value.get("c").get(1), &Value::Number(4i64.into()));
494 assert_eq!(value.get("d").get("e"), &Value::Str("alo".into()));
495 }
496
497 #[test]
498 fn number_test() -> io::Result<()> {
499 let data = r#"{"val1": 123.5, "val2": 123, "val3": -123}"#;
500 let value: Value<'_, Null, Null> = serde_json::from_str(data)?;
501 assert!(value.get("val1").is_f64());
502 assert!(!value.get("val1").is_u64());
503 assert!(!value.get("val1").is_i64());
504
505 assert!(!value.get("val2").is_f64());
506 assert!(value.get("val2").is_u64());
507 assert!(value.get("val2").is_i64());
508
509 assert!(!value.get("val3").is_f64());
510 assert!(!value.get("val3").is_u64());
511 assert!(value.get("val3").is_i64());
512
513 assert!(value.get("val1").as_f64().is_some());
514 assert!(value.get("val2").as_f64().is_some());
515 assert!(value.get("val3").as_f64().is_some());
516
517 assert!(value.get("val1").as_u64().is_none());
518 assert!(value.get("val2").as_u64().is_some());
519 assert!(value.get("val3").as_u64().is_none());
520
521 assert!(value.get("val1").as_i64().is_none());
522 assert!(value.get("val2").as_i64().is_some());
523 assert!(value.get("val3").as_i64().is_some());
524
525 Ok(())
526 }
527}