jsonbb/
value.rs

1// Copyright 2023 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use super::*;
16use bytes::BufMut;
17use std::{
18    fmt,
19    hash::{Hash, Hasher},
20    str::FromStr,
21};
22
23/// An owned JSON value.
24#[derive(Clone)]
25pub struct Value {
26    pub(crate) buffer: Box<[u8]>,
27}
28
29impl Value {
30    /// Returns a `null` value.
31    pub fn null() -> Self {
32        Self::from(())
33    }
34
35    /// Creates a new JSON array from an iterator of values.
36    pub fn array<'a>(iter: impl IntoIterator<Item = ValueRef<'a>>) -> Self {
37        Self::from_builder(0, |b| {
38            b.begin_array();
39            for v in iter {
40                b.add_value(v);
41            }
42            b.end_array();
43        })
44    }
45
46    /// Creates a new JSON object from an iterator of key-value pairs.
47    pub fn object<'a>(iter: impl IntoIterator<Item = (&'a str, ValueRef<'a>)>) -> Self {
48        Self::from_builder(0, |b| {
49            b.begin_object();
50            for (k, v) in iter {
51                b.add_string(k);
52                b.add_value(v);
53            }
54            b.end_object();
55        })
56    }
57
58    /// Deserialize an instance of `Value` from bytes of JSON text.
59    pub fn from_text(json: &[u8]) -> serde_json::Result<Self> {
60        use ::serde::de::DeserializeSeed;
61
62        let mut builder = Builder::with_capacity(json.len());
63        let mut deserializer = serde_json::Deserializer::from_slice(json);
64        builder.deserialize(&mut deserializer)?;
65        deserializer.end()?;
66        Ok(builder.finish())
67    }
68
69    /// Deserialize an instance of `Value` from bytes of JSON text.
70    #[cfg(feature = "simd-json")]
71    pub fn from_text_mut(json: &mut [u8]) -> simd_json::Result<Self> {
72        use ::serde::de::DeserializeSeed;
73
74        let mut builder = Builder::with_capacity(json.len());
75        let mut deserializer = simd_json::Deserializer::from_slice(json)?;
76        builder.deserialize(&mut deserializer)?;
77        Ok(builder.finish())
78    }
79
80    /// Creates a JSON `Value` from bytes of jsonbb encoding.
81    pub fn from_bytes(bytes: &[u8]) -> Self {
82        Self {
83            buffer: bytes.into(),
84        }
85    }
86
87    /// Returns a reference to the value.
88    pub fn as_ref(&self) -> ValueRef<'_> {
89        ValueRef::from_bytes(&self.buffer)
90    }
91
92    /// Returns the value as bytes.
93    pub fn as_bytes(&self) -> &[u8] {
94        &self.buffer
95    }
96
97    /// If the value is `null`, returns `()`. Returns `None` otherwise.
98    ///
99    /// # Example
100    ///
101    /// ```
102    /// let value = jsonbb::Value::from(());
103    /// assert_eq!(value.as_null(), Some(()));
104    /// ```
105    pub fn as_null(&self) -> Option<()> {
106        self.as_ref().as_null()
107    }
108
109    /// If the value is a boolean, returns the associated bool. Returns `None` otherwise.
110    ///
111    /// # Example
112    ///
113    /// ```
114    /// let value = jsonbb::Value::from(true);
115    /// assert_eq!(value.as_bool(), Some(true));
116    /// ```
117    pub fn as_bool(&self) -> Option<bool> {
118        self.as_ref().as_bool()
119    }
120
121    /// If the value is an integer, returns the associated i64. Returns `None` otherwise.
122    ///
123    /// # Example
124    ///
125    /// ```
126    /// let value = jsonbb::Value::from(1i64);
127    /// assert_eq!(value.as_i64(), Some(1));
128    /// ```
129    pub fn as_i64(&self) -> Option<i64> {
130        self.as_ref().as_i64()
131    }
132
133    /// If the value is an integer, returns the associated u64. Returns `None` otherwise.
134    ///
135    /// # Example
136    ///
137    /// ```
138    /// let value = jsonbb::Value::from(1i64);
139    /// assert_eq!(value.as_u64(), Some(1));
140    /// ```
141    pub fn as_u64(&self) -> Option<u64> {
142        self.as_ref().as_u64()
143    }
144
145    /// If the value is a float, returns the associated f64. Returns `None` otherwise.
146    ///
147    /// # Example
148    ///
149    /// ```
150    /// let value = jsonbb::Value::from(3.14_f64);
151    /// assert_eq!(value.as_f64(), Some(3.14));
152    /// ```
153    pub fn as_f64(&self) -> Option<f64> {
154        self.as_ref().as_f64()
155    }
156
157    /// If the value is a string, returns the associated str. Returns `None` otherwise.
158    ///
159    /// # Example
160    ///
161    /// ```
162    /// let value = jsonbb::Value::from("json");
163    /// assert_eq!(value.as_str(), Some("json"));
164    /// ```
165    pub fn as_str(&self) -> Option<&str> {
166        self.as_ref().as_str()
167    }
168
169    /// If the value is an array, returns the associated array. Returns `None` otherwise.
170    ///
171    /// # Example
172    ///
173    /// ```
174    /// let value: jsonbb::Value = "[]".parse().unwrap();
175    /// assert_eq!(value.as_array().unwrap().len(), 0);
176    /// ```
177    pub fn as_array(&self) -> Option<ArrayRef<'_>> {
178        self.as_ref().as_array()
179    }
180
181    /// If the value is an object, returns the associated map. Returns `None` otherwise.
182    ///
183    /// # Example
184    ///
185    /// ```
186    /// let value: jsonbb::Value = "{}".parse().unwrap();
187    /// assert_eq!(value.as_object().unwrap().len(), 0);
188    /// ```
189    pub fn as_object(&self) -> Option<ObjectRef<'_>> {
190        self.as_ref().as_object()
191    }
192
193    /// Returns true if the value is a null. Returns false otherwise.
194    ///
195    /// # Example
196    ///
197    /// ```
198    /// assert!(jsonbb::Value::from(()).is_null());
199    ///
200    /// // The boolean `false` is not null.
201    /// assert!(!jsonbb::Value::from(false).is_null());
202    /// ```
203    pub fn is_null(&self) -> bool {
204        self.as_ref().is_null()
205    }
206
207    /// Returns true if the value is a boolean. Returns false otherwise.
208    ///
209    /// # Example
210    ///
211    /// ```
212    /// assert!(jsonbb::Value::from(false).is_boolean());
213    ///
214    /// // The string `"false"` is a string, not a boolean.
215    /// assert!(!jsonbb::Value::from("false").is_boolean());
216    /// ```
217    pub fn is_boolean(&self) -> bool {
218        self.as_ref().is_boolean()
219    }
220
221    /// Returns true if the value is a number. Returns false otherwise.
222    ///
223    /// # Example
224    ///
225    /// ```
226    /// assert!(jsonbb::Value::from(1).is_number());
227    ///
228    /// // The string `"1"` is a string, not a number.
229    /// assert!(!jsonbb::Value::from("1").is_number());
230    /// ```
231    pub fn is_number(&self) -> bool {
232        self.as_ref().is_number()
233    }
234
235    /// Returns true if the value is an integer between zero and `u64::MAX`.
236    ///
237    /// # Example
238    ///
239    /// ```
240    /// assert!(jsonbb::Value::from(1i64).is_u64());
241    ///
242    /// // Negative integer.
243    /// assert!(!jsonbb::Value::from(-1i64).is_u64());
244    /// ```
245    pub fn is_u64(&self) -> bool {
246        self.as_ref().is_u64()
247    }
248
249    /// Returns true if the value is an integer between `i64::MIN` and `i64::MAX`.
250    ///
251    /// # Example
252    ///
253    /// ```
254    /// assert!(jsonbb::Value::from(1u64).is_i64());
255    ///
256    /// // Greater than i64::MAX.
257    /// assert!(!jsonbb::Value::from(u64::MAX).is_i64());
258    /// ```
259    pub fn is_i64(&self) -> bool {
260        self.as_ref().is_i64()
261    }
262
263    /// Returns true if the value is a number that can be represented by f64.
264    ///
265    /// # Example
266    ///
267    /// ```
268    /// assert!(jsonbb::Value::from(0f64).is_f64());
269    ///
270    /// // Integer
271    /// assert!(!jsonbb::Value::from(1i64).is_f64());
272    /// ```
273    pub fn is_f64(&self) -> bool {
274        self.as_ref().is_f64()
275    }
276
277    /// Returns true if the value is a string. Returns false otherwise.
278    ///
279    /// # Example
280    ///
281    /// ```
282    /// assert!(jsonbb::Value::from("string").is_string());
283    ///
284    /// // The boolean `false` is not a string.
285    /// assert!(!jsonbb::Value::from(false).is_string());
286    /// ```
287    pub fn is_string(&self) -> bool {
288        self.as_ref().is_string()
289    }
290
291    /// Returns true if the value is an array. Returns false otherwise.
292    pub fn is_array(&self) -> bool {
293        self.as_ref().is_array()
294    }
295
296    /// Returns true if the value is an object. Returns false otherwise.
297    pub fn is_object(&self) -> bool {
298        self.as_ref().is_object()
299    }
300
301    /// Returns the capacity of the internal buffer, in bytes.
302    pub fn capacity(&self) -> usize {
303        self.buffer.len()
304    }
305
306    /// Index into a JSON array or object.
307    ///
308    /// A string index can be used to access a value in an object,
309    /// and a usize index can be used to access an element of an array.
310    ///
311    /// # Example
312    ///
313    /// ```
314    /// let object: jsonbb::Value = r#"{"a": 1, "b": 2}"#.parse().unwrap();
315    /// assert_eq!(object.get("a").unwrap().to_string(), "1");
316    /// assert!(object.get("c").is_none());
317    /// assert!(object.get(0).is_none());
318    ///
319    /// let array: jsonbb::Value = r#"["a", "b"]"#.parse().unwrap();
320    /// assert_eq!(array.get(0).unwrap().to_string(), "\"a\"");
321    /// assert!(array.get(2).is_none());
322    /// assert!(array.get("a").is_none());
323    /// ```
324    pub fn get(&self, index: impl Index) -> Option<ValueRef<'_>> {
325        index.index_into(self.as_ref())
326    }
327
328    /// Looks up a value by a JSON Pointer.
329    ///
330    /// JSON Pointer defines a string syntax for identifying a specific value
331    /// within a JavaScript Object Notation (JSON) document.
332    ///
333    /// A Pointer is a Unicode string with the reference tokens separated by `/`.
334    /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The
335    /// addressed value is returned and if there is no such value `None` is
336    /// returned.
337    ///
338    /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901).
339    ///
340    /// # Examples
341    ///
342    /// ```
343    /// # use jsonbb::json;
344    /// #
345    /// let data = json!({
346    ///     "x": {
347    ///         "y": ["z", "zz"]
348    ///     }
349    /// });
350    ///
351    /// assert_eq!(data.pointer("/x/y/1").unwrap(), json!("zz").as_ref());
352    /// assert_eq!(data.pointer("/a/b/c"), None);
353    /// ```
354    pub fn pointer<'a>(&'a self, pointer: &str) -> Option<ValueRef<'a>> {
355        self.as_ref().pointer(pointer)
356    }
357
358    /// Push a value into a JSON array.
359    ///
360    /// This function is `O(N)` where N is the number of elements in the array.
361    ///
362    /// # Panics
363    ///
364    /// Panics if the value is not an array.
365    ///
366    /// # Example
367    /// ```
368    /// let mut array: jsonbb::Value = "[1]".parse().unwrap();
369    /// array.array_push(jsonbb::Value::from(()).as_ref());
370    /// array.array_push(jsonbb::Value::from(2).as_ref());
371    /// array.array_push(jsonbb::Value::from("str").as_ref());
372    /// array.array_push(jsonbb::Value::array([]).as_ref());
373    /// array.array_push(jsonbb::Value::object([]).as_ref());
374    /// assert_eq!(array.to_string(), r#"[1,null,2,"str",[],{}]"#);
375    /// ```
376    pub fn array_push(&mut self, value: ValueRef<'_>) {
377        let len = self.as_array().expect("not array").len();
378        // The offset to insert the value.
379        let offset = self.buffer.len() - 4 - 4 - 4 - 4 * len;
380        let mut buffer = std::mem::take(&mut self.buffer).into_vec();
381        // reserve space for the value + its entry
382        buffer.reserve_exact(value.capacity() + 4);
383        // remove tailing (len, size, entry)
384        buffer.truncate(buffer.len() - 12);
385        // insert the value
386        buffer.splice(offset..offset, value.as_slice().iter().copied());
387        // push the entry
388        buffer.put_slice(value.make_entry(offset).as_bytes());
389        // push (len, size, entry)
390        buffer.put_u32_ne((len + 1) as u32);
391        buffer.put_u32_ne((buffer.len() + 4) as u32);
392        buffer.put_slice(Entry::array(buffer.len()).as_bytes());
393        // store the buffer
394        self.buffer = buffer.into();
395    }
396
397    fn from_builder(capacity: usize, f: impl FnOnce(&mut Builder)) -> Self {
398        let mut builder = Builder::with_capacity(capacity);
399        f(&mut builder);
400        builder.finish()
401    }
402}
403
404impl fmt::Debug for Value {
405    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
406        self.as_ref().fmt(f)
407    }
408}
409
410/// Display a JSON value as a string.
411impl fmt::Display for Value {
412    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
413        self.as_ref().fmt(f)
414    }
415}
416
417/// # Example
418///
419/// ```
420/// let a: jsonbb::Value = r#"{"a": 1, "b": 2}"#.parse().unwrap();
421/// let b: jsonbb::Value = r#"{"b": 2, "a": 1.0}"#.parse().unwrap();
422/// assert_eq!(a, b);
423/// ```
424impl PartialEq for Value {
425    fn eq(&self, other: &Self) -> bool {
426        self.as_ref().eq(&other.as_ref())
427    }
428}
429
430impl Eq for Value {}
431
432impl PartialOrd for Value {
433    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
434        Some(self.cmp(other))
435    }
436}
437
438/// Compare two JSON values.
439///
440/// The ordering is defined as follows:
441/// <https://www.postgresql.org/docs/current/datatype-json.html#JSON-INDEXING>
442///
443/// # Example
444///
445/// ```
446/// use jsonbb::Value;
447///
448/// // Object > Array > Boolean > Number > String > Null
449/// let v = ["null", r#""str""#, "-1", "0", "3.14", "false", "true", "[]", "{}"];
450/// let v = v.iter().map(|s| s.parse().unwrap()).collect::<Vec<Value>>();
451/// for (i, a) in v.iter().enumerate() {
452///     for b in v.iter().skip(i + 1) {
453///         assert!(a < b);
454///     }
455/// }
456///
457/// // Array with n elements > array with n - 1 elements
458/// let a: Value = r#"[1, 2, 3]"#.parse().unwrap();
459/// let b: Value = r#"[1, 2]"#.parse().unwrap();
460/// assert!(a > b);
461///
462/// // arrays with equal numbers of elements are compared in the order:
463/// //  element-1, element-2 ...
464/// let a: Value = r#"[1, 2]"#.parse().unwrap();
465/// let b: Value = r#"[1, 3]"#.parse().unwrap();
466/// assert!(a < b);
467///
468/// // Object with n pairs > object with n - 1 pairs
469/// let a: Value = r#"{"a": 1, "b": 2}"#.parse().unwrap();
470/// let b: Value = r#"{"a": 1}"#.parse().unwrap();
471/// assert!(a > b);
472///
473/// // Objects with equal numbers of pairs are compared in the order:
474/// //  key-1, value-1, key-2 ...
475/// let a: Value = r#"{"a": 1, "b": 2}"#.parse().unwrap();
476/// let b: Value = r#"{"a": 2, "b": 1}"#.parse().unwrap();
477/// assert!(a < b);
478/// ```
479impl Ord for Value {
480    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
481        self.as_ref().cmp(&other.as_ref())
482    }
483}
484
485impl Hash for Value {
486    fn hash<H: Hasher>(&self, state: &mut H) {
487        self.as_ref().hash(state)
488    }
489}
490
491impl Default for Value {
492    fn default() -> Self {
493        Self::null()
494    }
495}
496
497impl From<serde_json::Value> for Value {
498    fn from(value: serde_json::Value) -> Self {
499        Self::from(&value)
500    }
501}
502
503impl From<&serde_json::Value> for Value {
504    fn from(value: &serde_json::Value) -> Self {
505        Self::from_builder(0, |b| b.add_serde_value(value))
506    }
507}
508
509impl From<serde_json::Number> for Value {
510    fn from(value: serde_json::Number) -> Self {
511        Self::from(&value)
512    }
513}
514
515impl From<&serde_json::Number> for Value {
516    fn from(n: &serde_json::Number) -> Self {
517        Self::from_builder(0, |b| b.add_serde_number(n))
518    }
519}
520
521impl From<Value> for serde_json::Value {
522    fn from(value: Value) -> Self {
523        value.as_ref().into()
524    }
525}
526
527impl<W: AsMut<Vec<u8>>> Builder<W> {
528    /// Adds a serde `Value` recursively to the builder and returns its ptr.
529    fn add_serde_value(&mut self, value: &serde_json::Value) {
530        match value {
531            serde_json::Value::Null => self.add_null(),
532            serde_json::Value::Bool(b) => self.add_bool(*b),
533            serde_json::Value::Number(n) => self.add_serde_number(n),
534            serde_json::Value::String(s) => self.add_string(s),
535            serde_json::Value::Array(a) => {
536                self.begin_array();
537                for v in a.iter() {
538                    self.add_serde_value(v);
539                }
540                self.end_array();
541            }
542            serde_json::Value::Object(o) => {
543                self.begin_object();
544                for (k, v) in o.iter() {
545                    self.add_string(k);
546                    self.add_serde_value(v);
547                }
548                self.end_object()
549            }
550        }
551    }
552
553    /// Adds a serde `Number`.
554    fn add_serde_number(&mut self, n: &serde_json::Number) {
555        if let Some(i) = n.as_u64() {
556            self.add_u64(i)
557        } else if let Some(i) = n.as_i64() {
558            self.add_i64(i)
559        } else if let Some(f) = n.as_f64() {
560            self.add_f64(f)
561        } else {
562            panic!("invalid number");
563        }
564    }
565}
566
567impl FromStr for Value {
568    type Err = serde_json::Error;
569
570    fn from_str(s: &str) -> Result<Self, Self::Err> {
571        Self::from_text(s.as_bytes())
572    }
573}
574
575impl From<()> for Value {
576    fn from(_: ()) -> Self {
577        Self::from_builder(4, |b| b.add_null())
578    }
579}
580
581impl From<bool> for Value {
582    fn from(v: bool) -> Self {
583        Self::from_builder(4, |b| b.add_bool(v))
584    }
585}
586
587impl From<u8> for Value {
588    fn from(v: u8) -> Self {
589        Self::from(v as u64)
590    }
591}
592
593impl From<u16> for Value {
594    fn from(v: u16) -> Self {
595        Self::from(v as u64)
596    }
597}
598
599impl From<u32> for Value {
600    fn from(v: u32) -> Self {
601        Self::from(v as u64)
602    }
603}
604
605impl From<u64> for Value {
606    fn from(v: u64) -> Self {
607        Self::from_builder(1 + 8 + 4, |b| b.add_u64(v))
608    }
609}
610
611impl From<usize> for Value {
612    fn from(v: usize) -> Self {
613        Self::from(v as u64)
614    }
615}
616
617impl From<i8> for Value {
618    fn from(v: i8) -> Self {
619        Self::from(v as i64)
620    }
621}
622
623impl From<i16> for Value {
624    fn from(v: i16) -> Self {
625        Self::from(v as i64)
626    }
627}
628
629impl From<i32> for Value {
630    fn from(v: i32) -> Self {
631        Self::from(v as i64)
632    }
633}
634
635impl From<i64> for Value {
636    fn from(v: i64) -> Self {
637        Self::from_builder(1 + 8 + 4, |b| b.add_i64(v))
638    }
639}
640
641impl From<isize> for Value {
642    fn from(v: isize) -> Self {
643        Self::from(v as u64)
644    }
645}
646
647impl From<f32> for Value {
648    fn from(v: f32) -> Self {
649        Self::from(v as f64)
650    }
651}
652
653impl From<f64> for Value {
654    fn from(v: f64) -> Self {
655        Self::from_builder(1 + 8 + 4, |b| b.add_f64(v))
656    }
657}
658
659impl From<&str> for Value {
660    fn from(s: &str) -> Self {
661        Self::from_builder(s.len() + 8, |b| b.add_string(s))
662    }
663}
664
665/// Creates a `Value` from bytes of jsonbb encoding.
666///
667/// If you want to create a `Value` from JSON text, use [`FromStr`] or [`from_text`] instead.
668///
669/// [`from_text`]: #method.from_text
670/// [`FromStr`]: #method.from_str
671impl From<&[u8]> for Value {
672    fn from(s: &[u8]) -> Self {
673        Self::from_bytes(s)
674    }
675}
676
677impl From<ValueRef<'_>> for Value {
678    fn from(v: ValueRef<'_>) -> Self {
679        Self::from_builder(v.capacity() + 4, |b| b.add_value(v))
680    }
681}
682
683#[cfg(test)]
684mod tests {
685    use super::*;
686
687    #[test]
688    fn from_serde() {
689        let serde_value: serde_json::Value = r#"
690        {
691            "name": "John Doe",
692            "age": 43,
693            "phones": [
694                "+44 1234567",
695                "+44 2345678"
696            ]
697        }"#
698        .parse()
699        .unwrap();
700        let _value = Value::from(&serde_value);
701    }
702
703    #[test]
704    #[should_panic]
705    fn from_nan() {
706        _ = Value::from(f64::NAN);
707    }
708
709    #[test]
710    #[should_panic]
711    fn from_inf() {
712        _ = Value::from(f64::INFINITY);
713    }
714
715    #[test]
716    #[should_panic]
717    fn from_neg_inf() {
718        _ = Value::from(f64::NEG_INFINITY);
719    }
720
721    #[test]
722    fn value_size() {
723        assert_eq!(Value::from(0).capacity(), 1 + 4);
724        assert_eq!(Value::from(1).capacity(), 1 + 1 + 4);
725        assert_eq!(Value::from(128).capacity(), 1 + 2 + 4);
726        assert_eq!(Value::from(32768).capacity(), 1 + 4 + 4);
727        assert_eq!(Value::from(2_147_483_648_u64).capacity(), 1 + 8 + 4);
728        assert_eq!(Value::from(i8::MIN).capacity(), 1 + 1 + 4);
729        assert_eq!(Value::from(i16::MIN).capacity(), 1 + 2 + 4);
730        assert_eq!(Value::from(i32::MIN).capacity(), 1 + 4 + 4);
731        assert_eq!(Value::from(i64::MIN).capacity(), 1 + 8 + 4);
732        assert_eq!(Value::from(0.0f32).capacity(), 1 + 8 + 4);
733        assert_eq!(Value::from(0.0f64).capacity(), 1 + 8 + 4);
734    }
735}