jsonbb/
value_ref.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 std::fmt;
16use std::hash::{Hash, Hasher};
17
18use super::*;
19use bytes::Buf;
20use serde_json::Number;
21
22/// A reference to a JSON value.
23#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
24pub enum ValueRef<'a> {
25    // NOTE: Order matters!
26    // we follow postgresql's order:
27    //  Object > Array > Boolean > Number > String > Null
28    /// Represents a JSON null value.
29    Null,
30    /// Represents a JSON string.
31    String(StringRef<'a>),
32    /// Represents a JSON number.
33    Number(NumberRef<'a>),
34    /// Represents a JSON boolean.
35    Bool(bool),
36    /// Represents a JSON array.
37    Array(ArrayRef<'a>),
38    /// Represents a JSON object.
39    Object(ObjectRef<'a>),
40}
41
42impl<'a> ValueRef<'a> {
43    /// Creates a `ValueRef` from a byte slice.
44    pub fn from_bytes(bytes: &[u8]) -> ValueRef<'_> {
45        let entry = Entry::from(&bytes[bytes.len() - 4..]);
46        ValueRef::from_slice(bytes, entry)
47    }
48
49    /// Returns true if the value is a null. Returns false otherwise.
50    pub fn is_null(self) -> bool {
51        matches!(self, Self::Null)
52    }
53
54    /// Returns true if the value is a boolean. Returns false otherwise.
55    pub fn is_boolean(self) -> bool {
56        matches!(self, Self::Bool(_))
57    }
58
59    /// Returns true if the value is a number. Returns false otherwise.
60    pub fn is_number(self) -> bool {
61        matches!(self, Self::Number(_))
62    }
63
64    /// Returns true if the value is an integer between zero and `u64::MAX`.
65    pub fn is_u64(self) -> bool {
66        matches!(self, Self::Number(n) if n.is_u64())
67    }
68
69    /// Returns true if the value is an integer between `i64::MIN` and `i64::MAX`.
70    pub fn is_i64(self) -> bool {
71        matches!(self, Self::Number(n) if n.is_i64())
72    }
73
74    /// Returns true if the value is a number that can be represented by f64.
75    pub fn is_f64(self) -> bool {
76        matches!(self, Self::Number(n) if n.is_f64())
77    }
78
79    /// Returns true if the value is a string. Returns false otherwise.
80    pub fn is_string(self) -> bool {
81        matches!(self, Self::String(_))
82    }
83
84    /// Returns true if the value is an array. Returns false otherwise.
85    pub fn is_array(self) -> bool {
86        matches!(self, Self::Array(_))
87    }
88
89    /// Returns true if the value is an object. Returns false otherwise.
90    pub fn is_object(self) -> bool {
91        matches!(self, Self::Object(_))
92    }
93
94    /// If the value is `null`, returns `()`. Returns `None` otherwise.
95    pub fn as_null(self) -> Option<()> {
96        match self {
97            Self::Null => Some(()),
98            _ => None,
99        }
100    }
101
102    /// If the value is a boolean, returns the associated bool. Returns `None` otherwise.
103    pub fn as_bool(self) -> Option<bool> {
104        match self {
105            Self::Bool(b) => Some(b),
106            _ => None,
107        }
108    }
109
110    /// If the value is a number, returns the associated number. Returns `None` otherwise.
111    pub fn as_number(self) -> Option<NumberRef<'a>> {
112        match self {
113            Self::Number(n) => Some(n),
114            _ => None,
115        }
116    }
117
118    /// If the value is an integer, returns the associated u64. Returns `None` otherwise.
119    pub fn as_u64(self) -> Option<u64> {
120        match self {
121            Self::Number(n) => n.as_u64(),
122            _ => None,
123        }
124    }
125
126    /// If the value is an integer, returns the associated i64. Returns `None` otherwise.
127    pub fn as_i64(self) -> Option<i64> {
128        match self {
129            Self::Number(n) => n.as_i64(),
130            _ => None,
131        }
132    }
133
134    /// If the value is a float, returns the associated f64. Returns `None` otherwise.
135    pub fn as_f64(self) -> Option<f64> {
136        match self {
137            Self::Number(n) => n.as_f64(),
138            _ => None,
139        }
140    }
141
142    /// If the value is a string, returns the associated str. Returns `None` otherwise.
143    pub fn as_str(self) -> Option<&'a str> {
144        match self {
145            Self::String(s) => Some(s.as_str()),
146            _ => None,
147        }
148    }
149
150    /// If the value is an array, returns the associated array. Returns `None` otherwise.
151    pub fn as_array(self) -> Option<ArrayRef<'a>> {
152        match self {
153            Self::Array(a) => Some(a),
154            _ => None,
155        }
156    }
157
158    /// If the value is an object, returns the associated map. Returns `None` otherwise.
159    pub fn as_object(self) -> Option<ObjectRef<'a>> {
160        match self {
161            Self::Object(o) => Some(o),
162            _ => None,
163        }
164    }
165
166    /// Creates owned `Value` from `ValueRef`.
167    pub fn to_owned(self) -> Value {
168        self.into()
169    }
170
171    pub(crate) fn from_slice(data: &'a [u8], entry: Entry) -> Self {
172        match entry.tag() {
173            Entry::NULL_TAG => Self::Null,
174            Entry::FALSE_TAG => Self::Bool(false),
175            Entry::TRUE_TAG => Self::Bool(true),
176            Entry::NUMBER_TAG => {
177                let ptr = entry.offset();
178                let data = &data[ptr..ptr + 1 + number_size(data[ptr])];
179                Self::Number(NumberRef { data })
180            }
181            Entry::STRING_TAG => {
182                let ptr = entry.offset();
183                let len = (&data[ptr..]).get_u32_ne() as usize;
184                Self::String(StringRef::from_bytes(&data[ptr..ptr + 4 + len]))
185            }
186            Entry::ARRAY_TAG => {
187                let ptr = entry.offset();
188                Self::Array(ArrayRef::from_slice(data, ptr))
189            }
190            Entry::OBJECT_TAG => {
191                let ptr = entry.offset();
192                Self::Object(ObjectRef::from_slice(data, ptr))
193            }
194            _ => panic!("invalid entry"),
195        }
196    }
197
198    /// Returns the entire value as a slice.
199    pub(crate) fn as_slice(self) -> &'a [u8] {
200        match self {
201            Self::Null => &[],
202            Self::Bool(_) => &[],
203            Self::Number(n) => n.data,
204            Self::String(s) => s.as_slice(),
205            Self::Array(a) => a.as_slice(),
206            Self::Object(o) => o.as_slice(),
207        }
208    }
209
210    /// Makes an entry from the value.
211    pub(crate) fn make_entry(self, offset: usize) -> Entry {
212        match self {
213            Self::Null => Entry::null(),
214            Self::Bool(b) => Entry::bool(b),
215            Self::Number(_) => Entry::number(offset),
216            Self::String(_) => Entry::string(offset),
217            Self::Array(a) => Entry::array(offset + a.as_slice().len()),
218            Self::Object(o) => Entry::object(offset + o.as_slice().len()),
219        }
220    }
221
222    /// Returns the entry and data of the value.
223    pub fn to_raw_parts(self) -> (Entry, &'a [u8]) {
224        (self.make_entry(0), self.as_slice())
225    }
226
227    /// Creates a `ValueRef` from an entry and data.
228    pub fn from_raw_parts(entry: Entry, data: &'a [u8]) -> Self {
229        Self::from_slice(data, entry)
230    }
231
232    /// Returns the capacity to store this value, in bytes.
233    pub fn capacity(self) -> usize {
234        self.as_slice().len()
235    }
236
237    /// Index into a JSON array or object.
238    /// A string index can be used to access a value in an object,
239    /// and a usize index can be used to access an element of an array.
240    pub fn get(self, index: impl Index) -> Option<ValueRef<'a>> {
241        index.index_into(self)
242    }
243
244    /// Looks up a value by a JSON Pointer.
245    pub fn pointer(self, pointer: &str) -> Option<Self> {
246        if pointer.is_empty() {
247            return Some(self);
248        }
249        if !pointer.starts_with('/') {
250            return None;
251        }
252
253        fn parse_index(s: &str) -> Option<usize> {
254            if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) {
255                return None;
256            }
257            s.parse().ok()
258        }
259
260        pointer
261            .split('/')
262            .skip(1)
263            .map(|x| x.replace("~1", "/").replace("~0", "~"))
264            .try_fold(self, |target, token| match target {
265                Self::Object(map) => map.get(&token),
266                Self::Array(list) => parse_index(&token).and_then(|x| list.get(x)),
267                _ => None,
268            })
269    }
270}
271
272impl fmt::Debug for ValueRef<'_> {
273    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
274        match self {
275            Self::Null => f.write_str("null"),
276            Self::Bool(b) => b.fmt(f),
277            Self::Number(n) => n.fmt(f),
278            Self::String(s) => s.as_str().fmt(f),
279            Self::Array(a) => a.fmt(f),
280            Self::Object(o) => o.fmt(f),
281        }
282    }
283}
284
285/// Display a JSON value as a string.
286impl fmt::Display for ValueRef<'_> {
287    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
288        serialize_in_json(self, f)
289    }
290}
291
292/// Build a `serde_json::Value` from a jsonbb node.
293impl From<ValueRef<'_>> for serde_json::Value {
294    fn from(value: ValueRef<'_>) -> Self {
295        match value {
296            ValueRef::Null => Self::Null,
297            ValueRef::Bool(b) => Self::Bool(b),
298            ValueRef::Number(n) => Self::Number(n.to_number()),
299            ValueRef::String(s) => Self::String(s.as_str().to_owned()),
300            ValueRef::Array(a) => Self::Array(a.iter().map(Self::from).collect()),
301            ValueRef::Object(o) => Self::Object(
302                o.iter()
303                    .map(|(k, v)| (k.to_owned(), Self::from(v)))
304                    .collect(),
305            ),
306        }
307    }
308}
309
310/// A reference to a JSON string.
311#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
312pub struct StringRef<'a> {
313    // # layout
314    // | len (u32) | bytes    |
315    // |    4      | 0..len  |
316    data: &'a [u8],
317}
318
319impl<'a> StringRef<'a> {
320    /// Creates a `StringRef` from a byte slice that contains the string data with length prefix.
321    pub(crate) fn from_bytes(data: &'a [u8]) -> Self {
322        Self { data }
323    }
324
325    /// Returns the string as a `&str`.
326    pub fn as_str(&self) -> &'a str {
327        let len = (&self.data[..4]).get_u32_ne() as usize;
328        // SAFETY: we don't check for utf8 validity because it's expensive
329        unsafe { std::str::from_utf8_unchecked(&self.data[4..4 + len]) }
330    }
331
332    /// Returns the entire string as a slice including the length prefix.
333    pub(crate) fn as_slice(&self) -> &'a [u8] {
334        self.data
335    }
336}
337
338/// A reference to a JSON number.
339#[derive(Clone, Copy)]
340pub struct NumberRef<'a> {
341    // # layout
342    // | tag | number    |
343    // |  1  | 0/1/2/4/8 |
344    data: &'a [u8],
345}
346
347impl NumberRef<'_> {
348    /// Dereferences the number.
349    pub fn to_number(self) -> Number {
350        let mut data = self.data;
351        match data.get_u8() {
352            NUMBER_ZERO => Number::from(0),
353            NUMBER_I8 => Number::from(data.get_i8()),
354            NUMBER_I16 => Number::from(data.get_i16_ne()),
355            NUMBER_I32 => Number::from(data.get_i32_ne()),
356            NUMBER_I64 => Number::from(data.get_i64_ne()),
357            NUMBER_U64 => Number::from(data.get_u64_ne()),
358            NUMBER_F64 => Number::from_f64(data.get_f64_ne()).unwrap(),
359            t => panic!("invalid number tag: {t}"),
360        }
361    }
362
363    /// If the number is an integer, returns the associated u64. Returns `None` otherwise.
364    pub fn as_u64(self) -> Option<u64> {
365        self.to_number().as_u64()
366    }
367
368    /// If the number is an integer, returns the associated i64. Returns `None` otherwise.
369    pub fn as_i64(self) -> Option<i64> {
370        self.to_number().as_i64()
371    }
372
373    /// Represents the number as f64 if possible. Returns None otherwise.
374    pub fn as_f64(self) -> Option<f64> {
375        self.to_number().as_f64()
376    }
377
378    /// Represents the number as f32 if possible. Returns None otherwise.
379    pub(crate) fn as_f32(&self) -> Option<f32> {
380        let mut data = self.data;
381        Some(match data.get_u8() {
382            NUMBER_ZERO => 0 as f32,
383            NUMBER_I8 => data.get_i8() as f32,
384            NUMBER_I16 => data.get_i16_ne() as f32,
385            NUMBER_I32 => data.get_i32_ne() as f32,
386            NUMBER_I64 => data.get_i64_ne() as f32,
387            NUMBER_U64 => data.get_u64_ne() as f32,
388            NUMBER_F64 => data.get_f64_ne() as f32,
389            t => panic!("invalid number tag: {t}"),
390        })
391    }
392
393    /// Returns true if the number can be represented by u64.
394    pub fn is_u64(self) -> bool {
395        self.to_number().is_u64()
396    }
397
398    /// Returns true if the number can be represented by i64.
399    pub fn is_i64(self) -> bool {
400        self.to_number().is_i64()
401    }
402
403    /// Returns true if the number can be represented by f64.
404    pub fn is_f64(self) -> bool {
405        self.to_number().is_f64()
406    }
407}
408
409impl fmt::Debug for NumberRef<'_> {
410    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
411        self.to_number().fmt(f)
412    }
413}
414
415impl fmt::Display for NumberRef<'_> {
416    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
417        self.to_number().fmt(f)
418    }
419}
420
421impl PartialEq for NumberRef<'_> {
422    fn eq(&self, other: &Self) -> bool {
423        let a = self.to_number();
424        let b = other.to_number();
425        match (a.as_u64(), b.as_u64()) {
426            (Some(a), Some(b)) => return a == b,           // a, b > 0
427            (Some(_), None) if b.is_i64() => return false, // a >= 0 > b
428            (None, Some(_)) if a.is_i64() => return false, // a < 0 <= b
429            (None, None) => {
430                if let (Some(a), Some(b)) = (a.as_i64(), b.as_i64()) {
431                    return a == b; // a, b < 0
432                }
433            }
434            _ => {}
435        }
436        // either a or b is a float
437        let a = a.as_f64().unwrap();
438        let b = b.as_f64().unwrap();
439        a == b
440    }
441}
442
443impl Eq for NumberRef<'_> {}
444
445impl PartialOrd for NumberRef<'_> {
446    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
447        Some(self.cmp(other))
448    }
449}
450
451impl Ord for NumberRef<'_> {
452    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
453        let a = self.to_number();
454        let b = other.to_number();
455        match (a.as_u64(), b.as_u64()) {
456            (Some(a), Some(b)) => return a.cmp(&b), // a, b > 0
457            (Some(_), None) if b.is_i64() => return std::cmp::Ordering::Greater, // a >= 0 > b
458            (None, Some(_)) if a.is_i64() => return std::cmp::Ordering::Less, // a < 0 <= b
459            (None, None) => {
460                if let (Some(a), Some(b)) = (a.as_i64(), b.as_i64()) {
461                    return a.cmp(&b); // a, b < 0
462                }
463            }
464            _ => {}
465        }
466        // either a or b is a float
467        let a = a.as_f64().unwrap();
468        let b = b.as_f64().unwrap();
469        a.partial_cmp(&b).expect("NaN or Inf in JSON number")
470    }
471}
472
473impl Hash for NumberRef<'_> {
474    fn hash<H: Hasher>(&self, state: &mut H) {
475        self.to_number().hash(state);
476    }
477}
478
479/// A reference to a JSON array.
480#[derive(Clone, Copy)]
481pub struct ArrayRef<'a> {
482    // # layout
483    //      v---------\
484    // | elements | [eptr] x len | len | size |
485    // |          |   4 x len    |  4  |  4   |
486    // |<----------- data (size) ------------>|^ptr
487    data: &'a [u8],
488}
489
490impl<'a> ArrayRef<'a> {
491    /// Returns the element at the given index, or `None` if the index is out of bounds.
492    pub fn get(self, index: usize) -> Option<ValueRef<'a>> {
493        let len = self.len();
494        if index >= len {
495            return None;
496        }
497        let offset = self.data.len() - 8 - 4 * (len - index);
498        let entry = Entry::from(&self.data[offset..offset + 4]);
499        Some(ValueRef::from_slice(self.data, entry))
500    }
501
502    /// Returns the number of elements in the array.
503    pub fn len(self) -> usize {
504        (&self.data[self.data.len() - 8..]).get_u32_ne() as usize
505    }
506
507    /// Returns `true` if the array contains no elements.
508    pub fn is_empty(self) -> bool {
509        self.len() == 0
510    }
511
512    /// Returns an iterator over the array's elements.
513    pub fn iter(self) -> impl ExactSizeIterator<Item = ValueRef<'a>> {
514        let len = self.len();
515        let offset = self.data.len() - 8 - 4 * len;
516        self.data[offset..offset + 4 * len]
517            .chunks_exact(4)
518            .map(|slice| ValueRef::from_slice(self.data, Entry::from(slice)))
519    }
520
521    /// Returns the entire array as a slice.
522    pub(crate) fn as_slice(self) -> &'a [u8] {
523        self.data
524    }
525
526    /// Creates an `ArrayRef` from a slice.
527    fn from_slice(data: &'a [u8], end: usize) -> Self {
528        let size = (&data[end - 4..end]).get_u32_ne() as usize;
529        Self {
530            data: &data[end - size..end],
531        }
532    }
533}
534
535impl fmt::Debug for ArrayRef<'_> {
536    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
537        f.debug_list().entries(self.iter()).finish()
538    }
539}
540
541/// Display a JSON array as a string.
542impl fmt::Display for ArrayRef<'_> {
543    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
544        serialize_in_json(self, f)
545    }
546}
547
548impl PartialEq for ArrayRef<'_> {
549    fn eq(&self, other: &Self) -> bool {
550        if self.len() != other.len() {
551            return false;
552        }
553        self.iter().eq(other.iter())
554    }
555}
556
557impl Eq for ArrayRef<'_> {}
558
559impl PartialOrd for ArrayRef<'_> {
560    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
561        Some(self.cmp(other))
562    }
563}
564
565impl Ord for ArrayRef<'_> {
566    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
567        // Array with n elements > array with n - 1 elements
568        match self.len().cmp(&other.len()) {
569            std::cmp::Ordering::Equal => self.iter().cmp(other.iter()),
570            ord => ord,
571        }
572    }
573}
574
575impl Hash for ArrayRef<'_> {
576    fn hash<H: Hasher>(&self, state: &mut H) {
577        for v in self.iter() {
578            v.hash(state);
579        }
580    }
581}
582
583/// A reference to a JSON object.
584#[derive(Clone, Copy)]
585pub struct ObjectRef<'a> {
586    // # layout
587    //      v-v------ \-----\
588    // | elements | [kptr, vptr] x len | len | size |
589    // |          |     4 x 2 x len    |  4  |  4   |
590    // |<-------------- data (size) --------------->|^ptr
591    //
592    // entries are ordered by key and each key is unique.
593    data: &'a [u8],
594}
595
596impl<'a> ObjectRef<'a> {
597    /// Returns the value associated with the given key, or `None` if the key is not present.
598    ///
599    /// # Examples
600    /// ```
601    /// let json: jsonbb::Value = r#"{"a": 1, "b": 2}"#.parse().unwrap();
602    /// let object = json.as_object().unwrap();
603    /// assert!(object.get("a").is_some());
604    /// assert!(object.get("c").is_none());
605    /// ```
606    pub fn get(self, key: &str) -> Option<ValueRef<'a>> {
607        // do binary search since entries are ordered by key
608        let entries = self.entries();
609        let idx = entries
610            .binary_search_by_key(&key, |&(kentry, _)| {
611                ValueRef::from_slice(self.data, kentry)
612                    .as_str()
613                    .expect("key must be string")
614            })
615            .ok()?;
616        let (_, ventry) = entries[idx];
617        Some(ValueRef::from_slice(self.data, ventry))
618    }
619
620    /// Returns `true` if the object contains a value for the specified key.
621    ///
622    /// # Examples
623    /// ```
624    /// let json: jsonbb::Value = r#"{"a": 1, "b": 2}"#.parse().unwrap();
625    /// let object = json.as_object().unwrap();
626    /// assert_eq!(object.contains_key("a"), true);
627    /// assert_eq!(object.contains_key("c"), false);
628    /// ```
629    pub fn contains_key(self, key: &str) -> bool {
630        // do binary search since entries are ordered by key
631        let entries = self.entries();
632        entries
633            .binary_search_by_key(&key, |&(kentry, _)| {
634                ValueRef::from_slice(self.data, kentry)
635                    .as_str()
636                    .expect("key must be string")
637            })
638            .is_ok()
639    }
640
641    /// Returns the number of elements in the object.
642    ///
643    /// # Examples
644    /// ```
645    /// let json: jsonbb::Value = r#"{"a": 1, "b": 2}"#.parse().unwrap();
646    /// let object = json.as_object().unwrap();
647    /// assert_eq!(object.len(), 2);
648    /// ```
649    pub fn len(self) -> usize {
650        (&self.data[self.data.len() - 8..]).get_u32_ne() as usize
651    }
652
653    /// Returns `true` if the object contains no elements.
654    ///
655    /// # Examples
656    /// ```
657    /// let json: jsonbb::Value = r#"{"a": 1, "b": 2}"#.parse().unwrap();
658    /// let object = json.as_object().unwrap();
659    /// assert_eq!(object.is_empty(), false);
660    /// ```
661    pub fn is_empty(self) -> bool {
662        self.len() == 0
663    }
664
665    /// Returns an iterator over the object's key-value pairs.
666    ///
667    /// # Examples
668    /// ```
669    /// let json: jsonbb::Value = r#"{"b": 2, "a": 1}"#.parse().unwrap();
670    /// let kvs: Vec<_> = json.as_object().unwrap().iter().map(|(k, v)| (k, v.as_u64().unwrap())).collect();
671    /// assert_eq!(kvs, [("a", 1), ("b", 2)]);
672    /// ```
673    pub fn iter(self) -> impl ExactSizeIterator<Item = (&'a str, ValueRef<'a>)> {
674        self.entries().iter().map(move |&(kentry, ventry)| {
675            let k = ValueRef::from_slice(self.data, kentry);
676            let v = ValueRef::from_slice(self.data, ventry);
677            (k.as_str().expect("key must be string"), v)
678        })
679    }
680
681    /// Returns an iterator over the object's keys.
682    ///
683    /// # Examples
684    /// ```
685    /// let json: jsonbb::Value = r#"{"b": 2, "a": 1}"#.parse().unwrap();
686    /// let keys: Vec<_> = json.as_object().unwrap().keys().collect();
687    /// assert_eq!(keys, ["a", "b"]);
688    /// ```
689    pub fn keys(self) -> impl ExactSizeIterator<Item = &'a str> {
690        self.iter().map(|(k, _)| k)
691    }
692
693    /// Returns an iterator over the object's values.
694    ///
695    /// # Examples
696    /// ```
697    /// let json: jsonbb::Value = r#"{"b": 2, "a": 1}"#.parse().unwrap();
698    /// let values: Vec<_> = json.as_object().unwrap().values().map(|v| v.as_u64().unwrap()).collect();
699    /// assert_eq!(values, [1, 2]);
700    /// ```
701    pub fn values(self) -> impl ExactSizeIterator<Item = ValueRef<'a>> {
702        self.iter().map(|(_, v)| v)
703    }
704
705    /// Returns the entire object as a slice.
706    pub(crate) fn as_slice(self) -> &'a [u8] {
707        self.data
708    }
709
710    /// Creates an `ObjectRef` from a slice.
711    fn from_slice(data: &'a [u8], end: usize) -> Self {
712        let size = (&data[end - 4..end]).get_u32_ne() as usize;
713        Self {
714            data: &data[end - size..end],
715        }
716    }
717
718    /// Returns the key-value entries.
719    fn entries(self) -> &'a [(Entry, Entry)] {
720        let len = self.len();
721        let base = self.data.len() - 8 - 8 * len;
722        let slice = &self.data[base..base + 8 * len];
723        unsafe { std::slice::from_raw_parts(slice.as_ptr() as _, len) }
724    }
725}
726
727impl fmt::Debug for ObjectRef<'_> {
728    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
729        f.debug_map().entries(self.iter()).finish()
730    }
731}
732
733/// Display a JSON object as a string.
734impl fmt::Display for ObjectRef<'_> {
735    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
736        serialize_in_json(self, f)
737    }
738}
739
740impl PartialEq for ObjectRef<'_> {
741    fn eq(&self, other: &Self) -> bool {
742        if self.len() != other.len() {
743            return false;
744        }
745        self.iter().eq(other.iter())
746    }
747}
748
749impl Eq for ObjectRef<'_> {}
750
751impl PartialOrd for ObjectRef<'_> {
752    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
753        Some(self.cmp(other))
754    }
755}
756
757impl Ord for ObjectRef<'_> {
758    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
759        // Object with n pairs > object with n - 1 pairs
760        match self.len().cmp(&other.len()) {
761            std::cmp::Ordering::Equal => self.iter().cmp(other.iter()),
762            ord => ord,
763        }
764    }
765}
766
767impl Hash for ObjectRef<'_> {
768    fn hash<H: Hasher>(&self, state: &mut H) {
769        for (k, v) in self.iter() {
770            k.hash(state);
771            v.hash(state);
772        }
773    }
774}
775
776/// Serialize a value in JSON format.
777fn serialize_in_json(value: &impl ::serde::Serialize, f: &mut fmt::Formatter<'_>) -> fmt::Result {
778    use std::io;
779
780    struct WriterFormatter<'a, 'b: 'a> {
781        inner: &'a mut fmt::Formatter<'b>,
782    }
783
784    impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> {
785        fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
786            // Safety: the serializer below only emits valid utf8 when using
787            // the default formatter.
788            let s = unsafe { std::str::from_utf8_unchecked(buf) };
789            self.inner.write_str(s).map_err(io_error)?;
790            Ok(buf.len())
791        }
792
793        fn flush(&mut self) -> io::Result<()> {
794            Ok(())
795        }
796    }
797
798    fn io_error(_: fmt::Error) -> io::Error {
799        // Error value does not matter because Display impl just maps it
800        // back to fmt::Error.
801        io::Error::other("fmt error")
802    }
803
804    let alternate = f.alternate();
805    let mut wr = WriterFormatter { inner: f };
806    if alternate {
807        // {:#}
808        value
809            .serialize(&mut serde_json::Serializer::pretty(&mut wr))
810            .map_err(|_| fmt::Error)
811    } else {
812        // {}
813        value
814            .serialize(&mut serde_json::Serializer::new(&mut wr))
815            .map_err(|_| fmt::Error)
816    }
817}
818
819/// A type that can be used to index into a `ValueRef`.
820pub trait Index: private::Sealed {
821    /// Return None if the key is not already in the array or object.
822    #[doc(hidden)]
823    fn index_into<'v>(&self, v: ValueRef<'v>) -> Option<ValueRef<'v>>;
824}
825
826impl Index for usize {
827    fn index_into<'v>(&self, v: ValueRef<'v>) -> Option<ValueRef<'v>> {
828        match v {
829            ValueRef::Array(a) => a.get(*self),
830            _ => None,
831        }
832    }
833}
834
835impl Index for str {
836    fn index_into<'v>(&self, v: ValueRef<'v>) -> Option<ValueRef<'v>> {
837        match v {
838            ValueRef::Object(o) => o.get(self),
839            _ => None,
840        }
841    }
842}
843
844impl Index for String {
845    fn index_into<'v>(&self, v: ValueRef<'v>) -> Option<ValueRef<'v>> {
846        match v {
847            ValueRef::Object(o) => o.get(self),
848            _ => None,
849        }
850    }
851}
852
853impl<T> Index for &T
854where
855    T: ?Sized + Index,
856{
857    fn index_into<'v>(&self, v: ValueRef<'v>) -> Option<ValueRef<'v>> {
858        (**self).index_into(v)
859    }
860}
861
862// Prevent users from implementing the Index trait.
863mod private {
864    pub trait Sealed {}
865    impl Sealed for usize {}
866    impl Sealed for str {}
867    impl Sealed for String {}
868    impl<T> Sealed for &T where T: ?Sized + Sealed {}
869}