Skip to main content

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}