sql_json_path/json/
mod.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
15//! Abstraction over JSON values.
16//!
17//! This module provides several traits to abstract over JSON values.
18//!
19//! - [`Json`]: A trait for owned JSON values.
20//! - [`JsonRef`]: A trait for borrowed JSON values.
21//! - [`ArrayRef`]: A trait for borrowed JSON arrays.
22//! - [`ObjectRef`]: A trait for borrowed JSON objects.
23
24use ::serde_json::Number;
25use std::fmt::{Debug, Display};
26
27#[cfg(feature = "jsonbb")]
28mod jsonbb;
29mod serde_json;
30#[cfg(feature = "simd-json")]
31mod simd_json;
32
33/// A borrowed or owned JSON value.
34///
35/// This type is used for the return type of [`JsonPath::query`]. It is similar to
36/// [`std::borrow::Cow`], but is specialized for [`Json`] and [`JsonRef`].
37///
38/// [`JsonPath::query`]: crate::JsonPath::query
39#[derive(Debug)]
40pub enum Cow<'a, T: Json + 'a> {
41    /// Borrowed data.
42    Borrowed(T::Borrowed<'a>),
43    /// Owned data.
44    Owned(T),
45}
46
47impl<'a, T: Json> Cow<'a, T> {
48    /// Returns a reference to the JSON value.
49    pub fn as_ref<'b>(&'b self) -> T::Borrowed<'b>
50    where
51        'a: 'b,
52    {
53        match self {
54            Cow::Borrowed(v) => T::borrow(*v),
55            Cow::Owned(v) => v.as_ref(),
56        }
57    }
58
59    /// Extracts the owned JSON.
60    ///
61    /// Clones the JSON if it is not already owned.
62    pub fn into_owned(self) -> T {
63        match self {
64            Cow::Borrowed(v) => v.to_owned(),
65            Cow::Owned(v) => v,
66        }
67    }
68}
69
70impl<T: Json> Display for Cow<'_, T>
71where
72    for<'a> T::Borrowed<'a>: Display,
73{
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        Display::fmt(&self.as_ref(), f)
76    }
77}
78
79/// A trait for owned JSON values.
80pub trait Json: Clone + Debug {
81    /// The type of borrowed JSON values.
82    type Borrowed<'a>: JsonRef<'a, Owned = Self>
83    where
84        Self: 'a;
85
86    /// Returns a reference to the JSON value.
87    fn as_ref(&self) -> Self::Borrowed<'_>;
88
89    /// Returns a null value.
90    fn null() -> Self;
91
92    /// Returns a boolean value.
93    fn bool(b: bool) -> Self;
94
95    /// Returns a number value from u64.
96    fn from_u64(v: u64) -> Self;
97
98    /// Returns a number value from i64.
99    fn from_i64(v: i64) -> Self;
100
101    /// Returns a number value from f64.
102    fn from_f64(v: f64) -> Self;
103
104    /// Returns a number value.
105    fn from_number(n: Number) -> Self;
106
107    /// Returns a string value.
108    fn from_string(s: &str) -> Self;
109
110    /// Returns an object.
111    fn object<'a, I: IntoIterator<Item = (&'a str, Self)>>(i: I) -> Self;
112
113    /// Narrow down the lifetime of a borrowed value.
114    fn borrow<'b, 'a: 'b>(p: Self::Borrowed<'a>) -> Self::Borrowed<'b> {
115        // SAFETY: 'a: 'b => T::Borrowed<'a>: T::Borrowed<'b>
116        unsafe { std::mem::transmute(p) }
117    }
118}
119
120/// A trait for borrowed JSON values.
121pub trait JsonRef<'a>: Copy + Debug {
122    /// The type of owned JSON values.
123    type Owned: Json<Borrowed<'a> = Self> + 'a;
124
125    /// The type of borrowed JSON arrays.
126    type Array: ArrayRef<'a, JsonRef = Self>;
127
128    /// The type of borrowed JSON objects.
129    type Object: ObjectRef<'a, JsonRef = Self>;
130
131    /// Creates an owned JSON value.
132    fn to_owned(self) -> Self::Owned;
133
134    /// Returns a null value.
135    fn null() -> Self;
136
137    /// If the JSON is a boolean, returns the associated bool. Returns `None` otherwise.
138    fn as_bool(self) -> Option<bool>;
139
140    /// If the JSON is a number, returns the associated number. Returns `None` otherwise.
141    fn as_number(self) -> Option<Number>;
142
143    /// If the JSON is a string, returns the associated string. Returns `None` otherwise.
144    fn as_str(self) -> Option<&'a str>;
145
146    /// If the JSON is an array, returns the associated array. Returns `None` otherwise.
147    fn as_array(self) -> Option<Self::Array>;
148
149    /// If the JSON is an object, returns the associated object. Returns `None` otherwise.
150    fn as_object(self) -> Option<Self::Object>;
151
152    /// Returns `true` if the value is null.
153    fn is_null(self) -> bool;
154
155    /// Returns `true` if the value is a boolean.
156    fn is_bool(self) -> bool {
157        self.as_bool().is_some()
158    }
159
160    /// Returns `true` if the value is a number.
161    fn is_number(self) -> bool {
162        self.as_number().is_some()
163    }
164
165    /// Returns `true` if the value is a string.
166    fn is_string(self) -> bool {
167        self.as_str().is_some()
168    }
169
170    /// Returns `true` if the value is an array.
171    fn is_array(self) -> bool {
172        self.as_array().is_some()
173    }
174
175    /// Returns `true` if the value is an object.
176    fn is_object(self) -> bool {
177        self.as_object().is_some()
178    }
179}
180
181/// A trait for borrowed JSON arrays.
182pub trait ArrayRef<'a>: Copy {
183    /// The type of borrowed JSON values.
184    type JsonRef: JsonRef<'a>;
185
186    /// Returns the length of the array.
187    fn len(self) -> usize;
188
189    /// Returns the value at the given index.
190    fn get(self, index: usize) -> Option<Self::JsonRef>;
191
192    /// Returns all values in the array.
193    fn list(self) -> Vec<Self::JsonRef>;
194
195    /// Returns `true` if the array is empty.
196    fn is_empty(self) -> bool {
197        self.len() == 0
198    }
199}
200
201/// A trait for borrowed JSON objects.
202pub trait ObjectRef<'a>: Copy {
203    /// The type of borrowed JSON values.
204    type JsonRef: JsonRef<'a>;
205
206    // Returns the number of elements in the object.
207    fn len(self) -> usize;
208
209    /// Returns the value associated with the given key.
210    fn get(self, key: &str) -> Option<Self::JsonRef>;
211
212    /// Returns all entries in the object.
213    fn list(self) -> Vec<(&'a str, Self::JsonRef)>;
214
215    /// Returns all values in the object.
216    fn list_value(self) -> Vec<Self::JsonRef>;
217
218    /// Returns `true` if the array is empty.
219    fn is_empty(self) -> bool {
220        self.len() == 0
221    }
222}