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