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