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}