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