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}