datatypes/json/
value.rs

1// Copyright 2023 Greptime Team
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::collections::BTreeMap;
16use std::fmt::{Display, Formatter};
17use std::hash::{Hash, Hasher};
18use std::sync::{Arc, OnceLock};
19
20use num_traits::ToPrimitive;
21use ordered_float::OrderedFloat;
22use serde::{Deserialize, Serialize};
23use serde_json::Number;
24
25use crate::data_type::ConcreteDataType;
26use crate::types::{JsonType, StructField, StructType};
27use crate::value::{ListValue, ListValueRef, StructValue, StructValueRef, Value, ValueRef};
28
29/// Number in json, can be a positive integer, a negative integer, or a floating number.
30/// Each of which is represented as `u64`, `i64` and `f64`.
31///
32/// This follows how `serde_json` designs number.
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
34pub enum JsonNumber {
35    PosInt(u64),
36    NegInt(i64),
37    Float(OrderedFloat<f64>),
38}
39
40impl JsonNumber {
41    fn as_u64(&self) -> Option<u64> {
42        match self {
43            JsonNumber::PosInt(n) => Some(*n),
44            JsonNumber::NegInt(n) => (*n >= 0).then_some(*n as u64),
45            _ => None,
46        }
47    }
48
49    fn as_i64(&self) -> Option<i64> {
50        match self {
51            JsonNumber::PosInt(n) => (*n <= i64::MAX as u64).then_some(*n as i64),
52            JsonNumber::NegInt(n) => Some(*n),
53            _ => None,
54        }
55    }
56
57    fn as_f64(&self) -> f64 {
58        match self {
59            JsonNumber::PosInt(n) => *n as f64,
60            JsonNumber::NegInt(n) => *n as f64,
61            JsonNumber::Float(n) => n.0,
62        }
63    }
64}
65
66impl From<u64> for JsonNumber {
67    fn from(i: u64) -> Self {
68        Self::PosInt(i)
69    }
70}
71
72impl From<i64> for JsonNumber {
73    fn from(n: i64) -> Self {
74        Self::NegInt(n)
75    }
76}
77
78impl From<f64> for JsonNumber {
79    fn from(i: f64) -> Self {
80        Self::Float(i.into())
81    }
82}
83
84impl Display for JsonNumber {
85    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
86        match self {
87            Self::PosInt(x) => write!(f, "{x}"),
88            Self::NegInt(x) => write!(f, "{x}"),
89            Self::Float(x) => write!(f, "{x}"),
90        }
91    }
92}
93
94/// Variants of json.
95///
96/// This follows how [serde_json::Value] designs except that we only choose to use [BTreeMap] to
97/// preserve the fields order by their names in the json object. (By default `serde_json` uses
98/// [BTreeMap], too. But it additionally supports "IndexMap" which preserves the order by insertion
99/// times of fields.)
100#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
101pub enum JsonVariant {
102    Null,
103    Bool(bool),
104    Number(JsonNumber),
105    String(String),
106    Array(Vec<JsonVariant>),
107    Object(BTreeMap<String, JsonVariant>),
108}
109
110impl JsonVariant {
111    fn json_type(&self) -> JsonType {
112        match self {
113            JsonVariant::Null => JsonType::new_native(ConcreteDataType::null_datatype()),
114            JsonVariant::Bool(_) => JsonType::new_native(ConcreteDataType::boolean_datatype()),
115            JsonVariant::Number(n) => JsonType::new_native(match n {
116                JsonNumber::PosInt(_) => ConcreteDataType::uint64_datatype(),
117                JsonNumber::NegInt(_) => ConcreteDataType::int64_datatype(),
118                JsonNumber::Float(_) => ConcreteDataType::float64_datatype(),
119            }),
120            JsonVariant::String(_) => JsonType::new_native(ConcreteDataType::string_datatype()),
121            JsonVariant::Array(array) => {
122                let item_type = if let Some(first) = array.first() {
123                    first.json_type().native_type()
124                } else {
125                    ConcreteDataType::null_datatype()
126                };
127                JsonType::new_native(ConcreteDataType::list_datatype(Arc::new(item_type)))
128            }
129            JsonVariant::Object(object) => {
130                let mut fields = Vec::with_capacity(object.len());
131                for (k, v) in object.iter() {
132                    fields.push(StructField::new(
133                        k.clone(),
134                        v.json_type().native_type(),
135                        true,
136                    ))
137                }
138                JsonType::new_native(ConcreteDataType::struct_datatype(StructType::new(
139                    Arc::new(fields),
140                )))
141            }
142        }
143    }
144
145    fn as_ref(&self) -> JsonVariantRef<'_> {
146        match self {
147            JsonVariant::Null => JsonVariantRef::Null,
148            JsonVariant::Bool(x) => (*x).into(),
149            JsonVariant::Number(x) => match x {
150                JsonNumber::PosInt(i) => (*i).into(),
151                JsonNumber::NegInt(i) => (*i).into(),
152                JsonNumber::Float(f) => (f.0).into(),
153            },
154            JsonVariant::String(x) => x.as_str().into(),
155            JsonVariant::Array(array) => {
156                JsonVariantRef::Array(array.iter().map(|x| x.as_ref()).collect())
157            }
158            JsonVariant::Object(object) => JsonVariantRef::Object(
159                object
160                    .iter()
161                    .map(|(k, v)| (k.as_str(), v.as_ref()))
162                    .collect(),
163            ),
164        }
165    }
166}
167
168impl From<()> for JsonVariant {
169    fn from(_: ()) -> Self {
170        Self::Null
171    }
172}
173
174impl From<bool> for JsonVariant {
175    fn from(v: bool) -> Self {
176        Self::Bool(v)
177    }
178}
179
180impl<T: Into<JsonNumber>> From<T> for JsonVariant {
181    fn from(v: T) -> Self {
182        Self::Number(v.into())
183    }
184}
185
186impl From<&str> for JsonVariant {
187    fn from(v: &str) -> Self {
188        Self::String(v.to_string())
189    }
190}
191
192impl From<String> for JsonVariant {
193    fn from(v: String) -> Self {
194        Self::String(v)
195    }
196}
197
198impl<const N: usize, T: Into<JsonVariant>> From<[T; N]> for JsonVariant {
199    fn from(vs: [T; N]) -> Self {
200        Self::Array(vs.into_iter().map(|x| x.into()).collect())
201    }
202}
203
204impl<K: Into<String>, V: Into<JsonVariant>, const N: usize> From<[(K, V); N]> for JsonVariant {
205    fn from(vs: [(K, V); N]) -> Self {
206        Self::Object(vs.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
207    }
208}
209
210impl Display for JsonVariant {
211    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
212        match self {
213            Self::Null => write!(f, "null"),
214            Self::Bool(x) => write!(f, "{x}"),
215            Self::Number(x) => write!(f, "{x}"),
216            Self::String(x) => write!(f, "{x}"),
217            Self::Array(array) => write!(
218                f,
219                "[{}]",
220                array
221                    .iter()
222                    .map(|x| x.to_string())
223                    .collect::<Vec<_>>()
224                    .join(", ")
225            ),
226            Self::Object(object) => {
227                write!(
228                    f,
229                    "{{ {} }}",
230                    object
231                        .iter()
232                        .map(|(k, v)| format!("{k}: {v}"))
233                        .collect::<Vec<_>>()
234                        .join(", ")
235                )
236            }
237        }
238    }
239}
240
241/// Represents any valid JSON value.
242#[derive(Debug, Eq, Serialize, Deserialize)]
243pub struct JsonValue {
244    #[serde(skip)]
245    json_type: OnceLock<JsonType>,
246    json_variant: JsonVariant,
247}
248
249impl JsonValue {
250    pub fn null() -> Self {
251        ().into()
252    }
253
254    pub(crate) fn new(json_variant: JsonVariant) -> Self {
255        Self {
256            json_type: OnceLock::new(),
257            json_variant,
258        }
259    }
260
261    pub(crate) fn data_type(&self) -> ConcreteDataType {
262        ConcreteDataType::Json(self.json_type().clone())
263    }
264
265    pub(crate) fn json_type(&self) -> &JsonType {
266        self.json_type.get_or_init(|| self.json_variant.json_type())
267    }
268
269    pub(crate) fn is_null(&self) -> bool {
270        matches!(self.json_variant, JsonVariant::Null)
271    }
272
273    pub(crate) fn as_i64(&self) -> Option<i64> {
274        match self.json_variant {
275            JsonVariant::Number(n) => n.as_i64(),
276            _ => None,
277        }
278    }
279
280    pub(crate) fn as_u64(&self) -> Option<u64> {
281        match self.json_variant {
282            JsonVariant::Number(n) => n.as_u64(),
283            _ => None,
284        }
285    }
286
287    pub(crate) fn as_f64(&self) -> Option<f64> {
288        match self.json_variant {
289            JsonVariant::Number(n) => Some(n.as_f64()),
290            _ => None,
291        }
292    }
293
294    pub(crate) fn as_f64_lossy(&self) -> Option<f64> {
295        match self.json_variant {
296            JsonVariant::Number(n) => Some(match n {
297                JsonNumber::PosInt(i) => i as f64,
298                JsonNumber::NegInt(i) => i as f64,
299                JsonNumber::Float(f) => f.0,
300            }),
301            _ => None,
302        }
303    }
304
305    pub(crate) fn as_bool(&self) -> Option<bool> {
306        match self.json_variant {
307            JsonVariant::Bool(b) => Some(b),
308            _ => None,
309        }
310    }
311
312    pub fn as_ref(&self) -> JsonValueRef<'_> {
313        JsonValueRef {
314            json_type: OnceLock::new(),
315            json_variant: self.json_variant.as_ref(),
316        }
317    }
318
319    pub fn into_variant(self) -> JsonVariant {
320        self.json_variant
321    }
322
323    pub(crate) fn into_value(self) -> Value {
324        fn helper(v: JsonVariant) -> Value {
325            match v {
326                JsonVariant::Null => Value::Null,
327                JsonVariant::Bool(x) => Value::Boolean(x),
328                JsonVariant::Number(x) => match x {
329                    JsonNumber::PosInt(i) => Value::UInt64(i),
330                    JsonNumber::NegInt(i) => Value::Int64(i),
331                    JsonNumber::Float(f) => Value::Float64(f),
332                },
333                JsonVariant::String(x) => Value::String(x.into()),
334                JsonVariant::Array(array) => {
335                    let item_type = if let Some(first) = array.first() {
336                        first.json_type().native_type()
337                    } else {
338                        ConcreteDataType::null_datatype()
339                    };
340                    Value::List(ListValue::new(
341                        array.into_iter().map(helper).collect(),
342                        Arc::new(item_type),
343                    ))
344                }
345                JsonVariant::Object(object) => {
346                    let mut fields = Vec::with_capacity(object.len());
347                    let mut items = Vec::with_capacity(object.len());
348                    for (k, v) in object {
349                        fields.push(StructField::new(k, v.json_type().native_type(), true));
350                        items.push(helper(v));
351                    }
352                    Value::Struct(StructValue::new(items, StructType::new(Arc::new(fields))))
353                }
354            }
355        }
356        helper(self.json_variant)
357    }
358}
359
360impl<T: Into<JsonVariant>> From<T> for JsonValue {
361    fn from(v: T) -> Self {
362        Self {
363            json_type: OnceLock::new(),
364            json_variant: v.into(),
365        }
366    }
367}
368
369impl From<JsonValue> for serde_json::Value {
370    fn from(v: JsonValue) -> Self {
371        fn helper(v: JsonVariant) -> serde_json::Value {
372            match v {
373                JsonVariant::Null => serde_json::Value::Null,
374                JsonVariant::Bool(x) => serde_json::Value::Bool(x),
375                JsonVariant::Number(x) => match x {
376                    JsonNumber::PosInt(i) => serde_json::Value::Number(i.into()),
377                    JsonNumber::NegInt(i) => serde_json::Value::Number(i.into()),
378                    JsonNumber::Float(f) => {
379                        if let Some(x) = Number::from_f64(f.0) {
380                            serde_json::Value::Number(x)
381                        } else {
382                            serde_json::Value::String("NaN".into())
383                        }
384                    }
385                },
386                JsonVariant::String(x) => serde_json::Value::String(x),
387                JsonVariant::Array(array) => {
388                    serde_json::Value::Array(array.into_iter().map(helper).collect())
389                }
390                JsonVariant::Object(object) => serde_json::Value::Object(
391                    object.into_iter().map(|(k, v)| (k, helper(v))).collect(),
392                ),
393            }
394        }
395        helper(v.json_variant)
396    }
397}
398
399impl Clone for JsonValue {
400    fn clone(&self) -> Self {
401        let Self {
402            json_type: _,
403            json_variant,
404        } = self;
405        Self {
406            json_type: OnceLock::new(),
407            json_variant: json_variant.clone(),
408        }
409    }
410}
411
412impl PartialEq<JsonValue> for JsonValue {
413    fn eq(&self, other: &JsonValue) -> bool {
414        let Self {
415            json_type: _,
416            json_variant,
417        } = self;
418        json_variant.eq(&other.json_variant)
419    }
420}
421
422impl Hash for JsonValue {
423    fn hash<H: Hasher>(&self, state: &mut H) {
424        let Self {
425            json_type: _,
426            json_variant,
427        } = self;
428        json_variant.hash(state);
429    }
430}
431
432impl Display for JsonValue {
433    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
434        write!(f, "{}", self.json_variant)
435    }
436}
437
438/// References of variants of json.
439#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
440pub enum JsonVariantRef<'a> {
441    Null,
442    Bool(bool),
443    Number(JsonNumber),
444    String(&'a str),
445    Array(Vec<JsonVariantRef<'a>>),
446    Object(BTreeMap<&'a str, JsonVariantRef<'a>>),
447}
448
449impl JsonVariantRef<'_> {
450    fn json_type(&self) -> JsonType {
451        match self {
452            JsonVariantRef::Null => JsonType::new_native(ConcreteDataType::null_datatype()),
453            JsonVariantRef::Bool(_) => JsonType::new_native(ConcreteDataType::boolean_datatype()),
454            JsonVariantRef::Number(n) => JsonType::new_native(match n {
455                JsonNumber::PosInt(_) => ConcreteDataType::uint64_datatype(),
456                JsonNumber::NegInt(_) => ConcreteDataType::int64_datatype(),
457                JsonNumber::Float(_) => ConcreteDataType::float64_datatype(),
458            }),
459            JsonVariantRef::String(_) => JsonType::new_native(ConcreteDataType::string_datatype()),
460            JsonVariantRef::Array(array) => {
461                let item_type = if let Some(first) = array.first() {
462                    first.json_type().native_type()
463                } else {
464                    ConcreteDataType::null_datatype()
465                };
466                JsonType::new_native(ConcreteDataType::list_datatype(Arc::new(item_type)))
467            }
468            JsonVariantRef::Object(object) => {
469                let mut fields = Vec::with_capacity(object.len());
470                for (k, v) in object.iter() {
471                    fields.push(StructField::new(
472                        k.to_string(),
473                        v.json_type().native_type(),
474                        true,
475                    ))
476                }
477                JsonType::new_native(ConcreteDataType::struct_datatype(StructType::new(
478                    Arc::new(fields),
479                )))
480            }
481        }
482    }
483}
484
485impl From<()> for JsonVariantRef<'_> {
486    fn from(_: ()) -> Self {
487        Self::Null
488    }
489}
490
491impl From<bool> for JsonVariantRef<'_> {
492    fn from(v: bool) -> Self {
493        Self::Bool(v)
494    }
495}
496
497impl<T: Into<JsonNumber>> From<T> for JsonVariantRef<'_> {
498    fn from(v: T) -> Self {
499        Self::Number(v.into())
500    }
501}
502
503impl<'a> From<&'a str> for JsonVariantRef<'a> {
504    fn from(v: &'a str) -> Self {
505        Self::String(v)
506    }
507}
508
509impl<'a, const N: usize, T: Into<JsonVariantRef<'a>>> From<[T; N]> for JsonVariantRef<'a> {
510    fn from(vs: [T; N]) -> Self {
511        Self::Array(vs.into_iter().map(|x| x.into()).collect())
512    }
513}
514
515impl<'a, V: Into<JsonVariantRef<'a>>, const N: usize> From<[(&'a str, V); N]>
516    for JsonVariantRef<'a>
517{
518    fn from(vs: [(&'a str, V); N]) -> Self {
519        Self::Object(vs.into_iter().map(|(k, v)| (k, v.into())).collect())
520    }
521}
522
523impl<'a> From<Vec<JsonVariantRef<'a>>> for JsonVariantRef<'a> {
524    fn from(v: Vec<JsonVariantRef<'a>>) -> Self {
525        Self::Array(v)
526    }
527}
528
529impl<'a> From<BTreeMap<&'a str, JsonVariantRef<'a>>> for JsonVariantRef<'a> {
530    fn from(v: BTreeMap<&'a str, JsonVariantRef<'a>>) -> Self {
531        Self::Object(v)
532    }
533}
534
535impl From<JsonVariantRef<'_>> for JsonVariant {
536    fn from(v: JsonVariantRef) -> Self {
537        match v {
538            JsonVariantRef::Null => Self::Null,
539            JsonVariantRef::Bool(x) => Self::Bool(x),
540            JsonVariantRef::Number(x) => Self::Number(x),
541            JsonVariantRef::String(x) => Self::String(x.to_string()),
542            JsonVariantRef::Array(array) => {
543                Self::Array(array.into_iter().map(Into::into).collect())
544            }
545            JsonVariantRef::Object(object) => Self::Object(
546                object
547                    .into_iter()
548                    .map(|(k, v)| (k.to_string(), v.into()))
549                    .collect(),
550            ),
551        }
552    }
553}
554
555/// Reference to representation of any valid JSON value.
556#[derive(Debug, Serialize)]
557pub struct JsonValueRef<'a> {
558    #[serde(skip)]
559    json_type: OnceLock<JsonType>,
560    json_variant: JsonVariantRef<'a>,
561}
562
563impl<'a> JsonValueRef<'a> {
564    pub fn null() -> Self {
565        ().into()
566    }
567
568    pub(crate) fn data_type(&self) -> ConcreteDataType {
569        ConcreteDataType::Json(self.json_type().clone())
570    }
571
572    pub(crate) fn json_type(&self) -> &JsonType {
573        self.json_type.get_or_init(|| self.json_variant.json_type())
574    }
575
576    pub fn into_variant(self) -> JsonVariantRef<'a> {
577        self.json_variant
578    }
579
580    pub(crate) fn is_null(&self) -> bool {
581        matches!(self.json_variant, JsonVariantRef::Null)
582    }
583
584    pub fn is_object(&self) -> bool {
585        matches!(self.json_variant, JsonVariantRef::Object(_))
586    }
587
588    pub(crate) fn as_f32(&self) -> Option<f32> {
589        match self.json_variant {
590            JsonVariantRef::Number(JsonNumber::Float(f)) => f.to_f32(),
591            _ => None,
592        }
593    }
594
595    pub(crate) fn as_f64(&self) -> Option<f64> {
596        match self.json_variant {
597            JsonVariantRef::Number(JsonNumber::Float(f)) => Some(f.0),
598            _ => None,
599        }
600    }
601
602    pub fn as_value_ref(&self) -> ValueRef<'_> {
603        fn helper<'a>(v: &'a JsonVariantRef) -> ValueRef<'a> {
604            match v {
605                JsonVariantRef::Null => ValueRef::Null,
606                JsonVariantRef::Bool(x) => ValueRef::Boolean(*x),
607                JsonVariantRef::Number(x) => match x {
608                    JsonNumber::PosInt(i) => ValueRef::UInt64(*i),
609                    JsonNumber::NegInt(i) => ValueRef::Int64(*i),
610                    JsonNumber::Float(f) => ValueRef::Float64(*f),
611                },
612                JsonVariantRef::String(x) => ValueRef::String(x),
613                JsonVariantRef::Array(array) => {
614                    let val = array.iter().map(helper).collect::<Vec<_>>();
615                    let item_datatype = if let Some(first) = val.first() {
616                        first.data_type()
617                    } else {
618                        ConcreteDataType::null_datatype()
619                    };
620                    ValueRef::List(ListValueRef::RefList {
621                        val,
622                        item_datatype: Arc::new(item_datatype),
623                    })
624                }
625                JsonVariantRef::Object(object) => {
626                    let mut fields = Vec::with_capacity(object.len());
627                    let mut val = Vec::with_capacity(object.len());
628                    for (k, v) in object.iter() {
629                        let v = helper(v);
630                        fields.push(StructField::new(k.to_string(), v.data_type(), true));
631                        val.push(v);
632                    }
633                    ValueRef::Struct(StructValueRef::RefList {
634                        val,
635                        fields: StructType::new(Arc::new(fields)),
636                    })
637                }
638            }
639        }
640        helper(&self.json_variant)
641    }
642
643    pub(crate) fn data_size(&self) -> usize {
644        size_of_val(self)
645    }
646}
647
648impl<'a, T: Into<JsonVariantRef<'a>>> From<T> for JsonValueRef<'a> {
649    fn from(v: T) -> Self {
650        Self {
651            json_type: OnceLock::new(),
652            json_variant: v.into(),
653        }
654    }
655}
656
657impl From<JsonValueRef<'_>> for JsonValue {
658    fn from(v: JsonValueRef<'_>) -> Self {
659        Self {
660            json_type: OnceLock::new(),
661            json_variant: v.json_variant.into(),
662        }
663    }
664}
665
666impl PartialEq for JsonValueRef<'_> {
667    fn eq(&self, other: &Self) -> bool {
668        let Self {
669            json_type: _,
670            json_variant,
671        } = self;
672        json_variant == &other.json_variant
673    }
674}
675
676impl Eq for JsonValueRef<'_> {}
677
678impl Clone for JsonValueRef<'_> {
679    fn clone(&self) -> Self {
680        let Self {
681            json_type: _,
682            json_variant,
683        } = self;
684        Self {
685            json_type: OnceLock::new(),
686            json_variant: json_variant.clone(),
687        }
688    }
689}