Skip to main content

blazingly_json/
value.rs

1use crate::{Error, Map, Number};
2use serde::de::{DeserializeOwned, MapAccess, SeqAccess, Visitor};
3use serde::{Deserialize, Serialize};
4use std::fmt;
5use std::mem;
6use std::ops::{Index, IndexMut};
7
8pub use crate::raw_value::{to_raw_value, RawValue};
9
10/// An owned JSON value.
11#[derive(Clone, Debug, Default, PartialEq)]
12pub enum Value {
13    #[default]
14    Null,
15    Bool(bool),
16    Number(Number),
17    String(String),
18    Array(Vec<Value>),
19    Object(Map<String, Value>),
20}
21
22impl Value {
23    #[must_use]
24    pub const fn is_null(&self) -> bool {
25        matches!(self, Self::Null)
26    }
27
28    #[must_use]
29    pub const fn is_boolean(&self) -> bool {
30        matches!(self, Self::Bool(_))
31    }
32
33    #[must_use]
34    pub const fn is_number(&self) -> bool {
35        matches!(self, Self::Number(_))
36    }
37
38    #[must_use]
39    pub fn is_i64(&self) -> bool {
40        self.as_i64().is_some()
41    }
42
43    #[must_use]
44    pub fn is_u64(&self) -> bool {
45        self.as_u64().is_some()
46    }
47
48    #[must_use]
49    pub fn is_f64(&self) -> bool {
50        matches!(self, Self::Number(number) if number.is_f64())
51    }
52
53    #[must_use]
54    pub const fn is_string(&self) -> bool {
55        matches!(self, Self::String(_))
56    }
57
58    #[must_use]
59    pub const fn is_array(&self) -> bool {
60        matches!(self, Self::Array(_))
61    }
62
63    #[must_use]
64    pub const fn is_object(&self) -> bool {
65        matches!(self, Self::Object(_))
66    }
67
68    #[must_use]
69    pub const fn as_bool(&self) -> Option<bool> {
70        match self {
71            Self::Bool(value) => Some(*value),
72            _ => None,
73        }
74    }
75
76    #[must_use]
77    pub fn as_i64(&self) -> Option<i64> {
78        match self {
79            Self::Number(value) => value.as_i64(),
80            _ => None,
81        }
82    }
83
84    #[must_use]
85    pub fn as_u64(&self) -> Option<u64> {
86        match self {
87            Self::Number(value) => value.as_u64(),
88            _ => None,
89        }
90    }
91
92    #[must_use]
93    pub fn as_f64(&self) -> Option<f64> {
94        match self {
95            Self::Number(value) => value.as_f64(),
96            _ => None,
97        }
98    }
99
100    #[must_use]
101    pub const fn as_number(&self) -> Option<&Number> {
102        match self {
103            Self::Number(value) => Some(value),
104            _ => None,
105        }
106    }
107
108    #[must_use]
109    pub fn as_str(&self) -> Option<&str> {
110        match self {
111            Self::String(value) => Some(value),
112            _ => None,
113        }
114    }
115
116    #[must_use]
117    pub const fn as_array(&self) -> Option<&Vec<Self>> {
118        match self {
119            Self::Array(value) => Some(value),
120            _ => None,
121        }
122    }
123
124    pub fn as_array_mut(&mut self) -> Option<&mut Vec<Self>> {
125        match self {
126            Self::Array(value) => Some(value),
127            _ => None,
128        }
129    }
130
131    #[must_use]
132    pub const fn as_object(&self) -> Option<&Map<String, Self>> {
133        match self {
134            Self::Object(value) => Some(value),
135            _ => None,
136        }
137    }
138
139    pub fn as_object_mut(&mut self) -> Option<&mut Map<String, Self>> {
140        match self {
141            Self::Object(value) => Some(value),
142            _ => None,
143        }
144    }
145
146    #[must_use]
147    pub fn get<I: ValueIndex>(&self, index: I) -> Option<&Self> {
148        index.index_into(self)
149    }
150
151    pub fn get_mut<I: ValueIndex>(&mut self, index: I) -> Option<&mut Self> {
152        index.index_into_mut(self)
153    }
154
155    /// Resolves an RFC 6901 JSON Pointer.
156    #[must_use]
157    pub fn pointer(&self, pointer: &str) -> Option<&Self> {
158        if pointer.is_empty() {
159            return Some(self);
160        }
161        if !pointer.starts_with('/') {
162            return None;
163        }
164        pointer.split('/').skip(1).try_fold(self, |value, token| {
165            let token = decode_pointer_token(token);
166            match value {
167                Self::Object(object) => object.get(token.as_ref()),
168                Self::Array(array) => array.get(parse_index(&token)?),
169                _ => None,
170            }
171        })
172    }
173
174    /// Resolves a mutable RFC 6901 JSON Pointer.
175    pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut Self> {
176        if pointer.is_empty() {
177            return Some(self);
178        }
179        if !pointer.starts_with('/') {
180            return None;
181        }
182        let tokens = pointer
183            .split('/')
184            .skip(1)
185            .map(decode_pointer_token)
186            .collect::<Vec<_>>();
187        let mut current = self;
188        for token in tokens {
189            current = match current {
190                Self::Object(object) => object.get_mut(token.as_ref())?,
191                Self::Array(array) => array.get_mut(parse_index(&token)?)?,
192                _ => return None,
193            };
194        }
195        Some(current)
196    }
197
198    /// Replaces this value with null and returns the previous value.
199    #[must_use]
200    pub fn take(&mut self) -> Self {
201        mem::take(self)
202    }
203}
204
205fn decode_pointer_token(token: &str) -> std::borrow::Cow<'_, str> {
206    if !token.as_bytes().contains(&b'~') {
207        return std::borrow::Cow::Borrowed(token);
208    }
209    std::borrow::Cow::Owned(token.replace("~1", "/").replace("~0", "~"))
210}
211
212fn parse_index(token: &str) -> Option<usize> {
213    if token.is_empty() || (token.len() > 1 && token.starts_with('0')) {
214        return None;
215    }
216    token.parse().ok()
217}
218
219/// Index accepted by [`Value::get`] and [`Value::get_mut`].
220pub trait ValueIndex: private::Sealed {
221    fn index_into(self, value: &Value) -> Option<&Value>;
222    fn index_into_mut(self, value: &mut Value) -> Option<&mut Value>;
223}
224
225mod private {
226    pub trait Sealed {}
227    impl Sealed for usize {}
228    impl Sealed for &str {}
229    impl Sealed for String {}
230    impl Sealed for &String {}
231}
232
233impl ValueIndex for usize {
234    fn index_into(self, value: &Value) -> Option<&Value> {
235        value.as_array()?.get(self)
236    }
237
238    fn index_into_mut(self, value: &mut Value) -> Option<&mut Value> {
239        value.as_array_mut()?.get_mut(self)
240    }
241}
242
243impl ValueIndex for &str {
244    fn index_into(self, value: &Value) -> Option<&Value> {
245        value.as_object()?.get(self)
246    }
247
248    fn index_into_mut(self, value: &mut Value) -> Option<&mut Value> {
249        value.as_object_mut()?.get_mut(self)
250    }
251}
252
253impl ValueIndex for String {
254    fn index_into(self, value: &Value) -> Option<&Value> {
255        value.as_object()?.get(&self)
256    }
257
258    fn index_into_mut(self, value: &mut Value) -> Option<&mut Value> {
259        value.as_object_mut()?.get_mut(&self)
260    }
261}
262
263impl ValueIndex for &String {
264    fn index_into(self, value: &Value) -> Option<&Value> {
265        value.as_object()?.get(self)
266    }
267
268    fn index_into_mut(self, value: &mut Value) -> Option<&mut Value> {
269        value.as_object_mut()?.get_mut(self)
270    }
271}
272
273static NULL: Value = Value::Null;
274
275impl Index<&str> for Value {
276    type Output = Self;
277
278    fn index(&self, index: &str) -> &Self::Output {
279        self.get(index).unwrap_or(&NULL)
280    }
281}
282
283impl IndexMut<&str> for Value {
284    fn index_mut(&mut self, index: &str) -> &mut Self::Output {
285        if self.is_null() {
286            *self = Self::Object(Map::new());
287        }
288        self.as_object_mut()
289            .expect("cannot access a non-object JSON value with a string")
290            .entry(index.to_owned())
291            .or_default()
292    }
293}
294
295impl Index<usize> for Value {
296    type Output = Self;
297
298    fn index(&self, index: usize) -> &Self::Output {
299        self.get(index).unwrap_or(&NULL)
300    }
301}
302
303impl IndexMut<usize> for Value {
304    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
305        &mut self
306            .as_array_mut()
307            .expect("cannot access a non-array JSON value with an integer")[index]
308    }
309}
310
311impl Serialize for Value {
312    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
313        match self {
314            Self::Null => serializer.serialize_unit(),
315            Self::Bool(value) => serializer.serialize_bool(*value),
316            Self::Number(value) => value.serialize(serializer),
317            Self::String(value) => serializer.serialize_str(value),
318            Self::Array(value) => value.serialize(serializer),
319            Self::Object(value) => value.serialize(serializer),
320        }
321    }
322}
323
324impl<'de> Deserialize<'de> for Value {
325    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
326        struct ValueVisitor;
327
328        impl<'de> Visitor<'de> for ValueVisitor {
329            type Value = Value;
330
331            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
332                formatter.write_str("any valid JSON value")
333            }
334
335            fn visit_unit<E>(self) -> Result<Self::Value, E> {
336                Ok(Value::Null)
337            }
338
339            fn visit_none<E>(self) -> Result<Self::Value, E> {
340                Ok(Value::Null)
341            }
342
343            fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> {
344                Ok(Value::Bool(value))
345            }
346
347            fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> {
348                Ok(Value::from(value))
349            }
350
351            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
352                Ok(Value::from(value))
353            }
354
355            fn visit_f64<E: serde::de::Error>(self, value: f64) -> Result<Self::Value, E> {
356                Number::from_f64(value)
357                    .map(Value::Number)
358                    .ok_or_else(|| E::custom("non-finite JSON number"))
359            }
360
361            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E> {
362                Ok(Value::String(value.to_owned()))
363            }
364
365            fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E> {
366                Ok(Value::String(value.to_owned()))
367            }
368
369            fn visit_string<E>(self, value: String) -> Result<Self::Value, E> {
370                Ok(Value::String(value))
371            }
372
373            fn visit_seq<A: SeqAccess<'de>>(
374                self,
375                mut sequence: A,
376            ) -> Result<Self::Value, A::Error> {
377                let mut values = Vec::with_capacity(sequence.size_hint().unwrap_or(0));
378                while let Some(value) = sequence.next_element()? {
379                    values.push(value);
380                }
381                Ok(Value::Array(values))
382            }
383
384            fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
385                let mut values = Map::new();
386                while let Some((key, value)) = map.next_entry()? {
387                    values.insert(key, value);
388                }
389                Ok(Value::Object(values))
390            }
391        }
392
393        deserializer.deserialize_any(ValueVisitor)
394    }
395}
396
397impl fmt::Display for Value {
398    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
399        match crate::to_string(self) {
400            Ok(encoded) => formatter.write_str(&encoded),
401            Err(_) => Err(fmt::Error),
402        }
403    }
404}
405
406impl From<()> for Value {
407    fn from((): ()) -> Self {
408        Self::Null
409    }
410}
411
412impl From<bool> for Value {
413    fn from(value: bool) -> Self {
414        Self::Bool(value)
415    }
416}
417
418impl From<String> for Value {
419    fn from(value: String) -> Self {
420        Self::String(value)
421    }
422}
423
424impl From<&str> for Value {
425    fn from(value: &str) -> Self {
426        Self::String(value.to_owned())
427    }
428}
429
430impl From<Number> for Value {
431    fn from(value: Number) -> Self {
432        Self::Number(value)
433    }
434}
435
436macro_rules! from_number {
437    ($($type:ty),+ $(,)?) => {
438        $(
439            impl From<$type> for Value {
440                fn from(value: $type) -> Self {
441                    Self::Number(Number::from(value))
442                }
443            }
444        )+
445    };
446}
447
448from_number!(i8, i16, i32, i64, isize, u8, u16, u32, u64, usize);
449
450impl From<f32> for Value {
451    fn from(value: f32) -> Self {
452        Number::from_f64(f64::from(value)).map_or(Self::Null, Self::Number)
453    }
454}
455
456impl From<f64> for Value {
457    fn from(value: f64) -> Self {
458        Number::from_f64(value).map_or(Self::Null, Self::Number)
459    }
460}
461
462impl<T: Into<Value>> From<Option<T>> for Value {
463    fn from(value: Option<T>) -> Self {
464        value.map_or(Self::Null, Into::into)
465    }
466}
467
468impl<T: Into<Value>> From<Vec<T>> for Value {
469    fn from(value: Vec<T>) -> Self {
470        Self::Array(value.into_iter().map(Into::into).collect())
471    }
472}
473
474macro_rules! partial_eq_value {
475    ($($type:ty),+ $(,)?) => {
476        $(
477            impl PartialEq<$type> for Value {
478                fn eq(&self, other: &$type) -> bool {
479                    self == &Value::from(*other)
480                }
481            }
482
483            impl PartialEq<Value> for $type {
484                fn eq(&self, other: &Value) -> bool {
485                    &Value::from(*self) == other
486                }
487            }
488        )+
489    };
490}
491
492partial_eq_value!(bool, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, f32, f64);
493
494impl PartialEq<str> for Value {
495    fn eq(&self, other: &str) -> bool {
496        self.as_str() == Some(other)
497    }
498}
499
500impl PartialEq<&str> for Value {
501    fn eq(&self, other: &&str) -> bool {
502        self.as_str() == Some(*other)
503    }
504}
505
506impl PartialEq<Value> for str {
507    fn eq(&self, other: &Value) -> bool {
508        other == self
509    }
510}
511
512impl PartialEq<Value> for &str {
513    fn eq(&self, other: &Value) -> bool {
514        other == *self
515    }
516}
517
518/// Deserializes a typed value directly from an owned [`Value`].
519///
520/// # Errors
521///
522/// Returns an error when the value does not match `T`.
523pub fn from_value<T: DeserializeOwned>(value: Value) -> Result<T, Error> {
524    T::deserialize(value)
525}