1use 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;
24use snafu::{OptionExt, ResultExt, ensure};
25
26use crate::Result;
27use crate::data_type::ConcreteDataType;
28use crate::error::{AlignJsonValueSnafu, SerializeSnafu};
29use crate::types::json_type::{JsonNativeType, JsonNumberType};
30use crate::types::{JsonType, StructField, StructType};
31use crate::value::{ListValue, ListValueRef, StructValue, StructValueRef, Value, ValueRef};
32
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
38pub enum JsonNumber {
39 PosInt(u64),
40 NegInt(i64),
41 Float(OrderedFloat<f64>),
42}
43
44impl JsonNumber {
45 fn as_u64(&self) -> Option<u64> {
46 match self {
47 JsonNumber::PosInt(n) => Some(*n),
48 JsonNumber::NegInt(n) => (*n >= 0).then_some(*n as u64),
49 _ => None,
50 }
51 }
52
53 fn as_i64(&self) -> Option<i64> {
54 match self {
55 JsonNumber::PosInt(n) => (*n <= i64::MAX as u64).then_some(*n as i64),
56 JsonNumber::NegInt(n) => Some(*n),
57 _ => None,
58 }
59 }
60
61 fn as_f64(&self) -> f64 {
62 match self {
63 JsonNumber::PosInt(n) => *n as f64,
64 JsonNumber::NegInt(n) => *n as f64,
65 JsonNumber::Float(n) => n.0,
66 }
67 }
68}
69
70impl From<u64> for JsonNumber {
71 fn from(i: u64) -> Self {
72 Self::PosInt(i)
73 }
74}
75
76impl From<i64> for JsonNumber {
77 fn from(n: i64) -> Self {
78 Self::NegInt(n)
79 }
80}
81
82impl From<f64> for JsonNumber {
83 fn from(i: f64) -> Self {
84 Self::Float(i.into())
85 }
86}
87
88impl From<Number> for JsonNumber {
89 fn from(n: Number) -> Self {
90 if let Some(i) = n.as_i64() {
91 i.into()
92 } else if let Some(i) = n.as_u64() {
93 i.into()
94 } else {
95 n.as_f64().unwrap_or(f64::NAN).into()
96 }
97 }
98}
99
100impl Display for JsonNumber {
101 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
102 match self {
103 Self::PosInt(x) => write!(f, "{x}"),
104 Self::NegInt(x) => write!(f, "{x}"),
105 Self::Float(x) => write!(f, "{x}"),
106 }
107 }
108}
109
110#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
112pub enum JsonVariant {
113 #[default]
114 Null,
115 Bool(bool),
116 Number(JsonNumber),
117 String(String),
118 Array(Vec<JsonVariant>),
119 Object(BTreeMap<String, JsonVariant>),
120 Variant(Vec<u8>),
122}
123
124impl JsonVariant {
125 pub(crate) fn as_i64(&self) -> Option<i64> {
126 match self {
127 JsonVariant::Number(n) => n.as_i64(),
128 _ => None,
129 }
130 }
131
132 pub(crate) fn as_u64(&self) -> Option<u64> {
133 match self {
134 JsonVariant::Number(n) => n.as_u64(),
135 _ => None,
136 }
137 }
138
139 pub(crate) fn as_f64(&self) -> Option<f64> {
140 match self {
141 JsonVariant::Number(n) => Some(n.as_f64()),
142 _ => None,
143 }
144 }
145
146 pub(crate) fn native_type(&self) -> JsonNativeType {
147 match self {
148 JsonVariant::Null => JsonNativeType::Null,
149 JsonVariant::Bool(_) => JsonNativeType::Bool,
150 JsonVariant::Number(n) => match n {
151 JsonNumber::PosInt(_) => JsonNativeType::u64(),
152 JsonNumber::NegInt(_) => JsonNativeType::i64(),
153 JsonNumber::Float(_) => JsonNativeType::f64(),
154 },
155 JsonVariant::String(_) => JsonNativeType::String,
156 JsonVariant::Array(array) => {
157 let item_type = if let Some(first) = array.first() {
158 first.native_type()
159 } else {
160 JsonNativeType::Null
161 };
162 JsonNativeType::Array(Box::new(item_type))
163 }
164 JsonVariant::Object(object) => JsonNativeType::Object(
165 object
166 .iter()
167 .map(|(k, v)| (k.clone(), v.native_type()))
168 .collect(),
169 ),
170 JsonVariant::Variant(_) => JsonNativeType::Variant,
171 }
172 }
173
174 fn json_type(&self) -> JsonType {
175 JsonType::new_json2(self.native_type())
176 }
177
178 fn as_ref(&self) -> JsonVariantRef<'_> {
179 match self {
180 JsonVariant::Null => JsonVariantRef::Null,
181 JsonVariant::Bool(x) => (*x).into(),
182 JsonVariant::Number(x) => match x {
183 JsonNumber::PosInt(i) => (*i).into(),
184 JsonNumber::NegInt(i) => (*i).into(),
185 JsonNumber::Float(f) => (f.0).into(),
186 },
187 JsonVariant::String(x) => x.as_str().into(),
188 JsonVariant::Array(array) => {
189 JsonVariantRef::Array(array.iter().map(|x| x.as_ref()).collect())
190 }
191 JsonVariant::Object(object) => JsonVariantRef::Object(
192 object
193 .iter()
194 .map(|(k, v)| (k.as_str(), v.as_ref()))
195 .collect(),
196 ),
197 JsonVariant::Variant(v) => JsonVariantRef::Variant(v),
198 }
199 }
200}
201
202impl From<()> for JsonVariant {
203 fn from(_: ()) -> Self {
204 Self::Null
205 }
206}
207
208impl From<bool> for JsonVariant {
209 fn from(v: bool) -> Self {
210 Self::Bool(v)
211 }
212}
213
214impl<T: Into<JsonNumber>> From<T> for JsonVariant {
215 fn from(v: T) -> Self {
216 Self::Number(v.into())
217 }
218}
219
220impl From<&str> for JsonVariant {
221 fn from(v: &str) -> Self {
222 Self::String(v.to_string())
223 }
224}
225
226impl From<String> for JsonVariant {
227 fn from(v: String) -> Self {
228 Self::String(v)
229 }
230}
231
232impl<const N: usize, T: Into<JsonVariant>> From<[T; N]> for JsonVariant {
233 fn from(vs: [T; N]) -> Self {
234 Self::Array(vs.into_iter().map(|x| x.into()).collect())
235 }
236}
237
238impl<K: Into<String>, V: Into<JsonVariant>, const N: usize> From<[(K, V); N]> for JsonVariant {
239 fn from(vs: [(K, V); N]) -> Self {
240 Self::Object(vs.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
241 }
242}
243
244impl From<serde_json::Value> for JsonVariant {
245 fn from(v: serde_json::Value) -> Self {
246 fn helper(v: serde_json::Value) -> JsonVariant {
247 match v {
248 serde_json::Value::Null => JsonVariant::Null,
249 serde_json::Value::Bool(b) => b.into(),
250 serde_json::Value::Number(n) => n.into(),
251 serde_json::Value::String(s) => s.into(),
252 serde_json::Value::Array(array) => {
253 JsonVariant::Array(array.into_iter().map(helper).collect())
254 }
255 serde_json::Value::Object(object) => {
256 JsonVariant::Object(object.into_iter().map(|(k, v)| (k, helper(v))).collect())
257 }
258 }
259 }
260 helper(v)
261 }
262}
263
264impl From<BTreeMap<String, JsonVariant>> for JsonVariant {
265 fn from(v: BTreeMap<String, JsonVariant>) -> Self {
266 Self::Object(v)
267 }
268}
269
270impl Display for JsonVariant {
271 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
272 match self {
273 Self::Null => write!(f, "null"),
274 Self::Bool(x) => write!(f, "{x}"),
275 Self::Number(x) => write!(f, "{x}"),
276 Self::String(x) => write!(f, "{x}"),
277 Self::Array(array) => write!(
278 f,
279 "[{}]",
280 array
281 .iter()
282 .map(|x| x.to_string())
283 .collect::<Vec<_>>()
284 .join(", ")
285 ),
286 Self::Object(object) => {
287 write!(
288 f,
289 "{{ {} }}",
290 object
291 .iter()
292 .map(|(k, v)| format!("{k}: {v}"))
293 .collect::<Vec<_>>()
294 .join(", ")
295 )
296 }
297 Self::Variant(x) => {
298 let result: serde_json::Result<serde_json::Value> = serde_json::from_slice(x);
299 match result {
300 Ok(v) => write!(f, "{v}"),
301 Err(_) => write!(f, "{x:?}"),
302 }
303 }
304 }
305 }
306}
307
308#[derive(Debug, Eq, Serialize, Deserialize)]
310pub struct JsonValue {
311 #[serde(skip)]
312 json_type: OnceLock<JsonType>,
313 json_variant: JsonVariant,
314}
315
316impl JsonValue {
317 pub fn null() -> Self {
318 ().into()
319 }
320
321 pub(crate) fn new(json_variant: JsonVariant) -> Self {
322 Self {
323 json_type: OnceLock::new(),
324 json_variant,
325 }
326 }
327
328 pub(crate) fn data_type(&self) -> ConcreteDataType {
329 ConcreteDataType::Json(self.json_type().clone())
330 }
331
332 pub fn json_type(&self) -> &JsonType {
333 self.json_type.get_or_init(|| self.json_variant.json_type())
334 }
335
336 pub(crate) fn is_null(&self) -> bool {
337 matches!(self.json_variant, JsonVariant::Null)
338 }
339
340 pub fn is_empty_object(&self) -> bool {
342 match &self.json_variant {
343 JsonVariant::Object(object) => object.is_empty(),
344 _ => false,
345 }
346 }
347
348 pub(crate) fn as_i64(&self) -> Option<i64> {
349 self.json_variant.as_i64()
350 }
351
352 pub(crate) fn as_u64(&self) -> Option<u64> {
353 self.json_variant.as_u64()
354 }
355
356 pub(crate) fn as_f64_lossy(&self) -> Option<f64> {
357 match self.json_variant {
358 JsonVariant::Number(n) => Some(match n {
359 JsonNumber::PosInt(i) => i as f64,
360 JsonNumber::NegInt(i) => i as f64,
361 JsonNumber::Float(f) => f.0,
362 }),
363 _ => None,
364 }
365 }
366
367 pub(crate) fn as_bool(&self) -> Option<bool> {
368 match self.json_variant {
369 JsonVariant::Bool(b) => Some(b),
370 _ => None,
371 }
372 }
373
374 pub fn as_ref(&self) -> JsonValueRef<'_> {
375 JsonValueRef {
376 json_type: OnceLock::new(),
377 json_variant: self.json_variant.as_ref(),
378 }
379 }
380
381 pub fn into_variant(self) -> JsonVariant {
382 self.json_variant
383 }
384
385 pub(crate) fn into_value(self) -> Value {
386 fn helper(v: JsonVariant) -> Value {
387 match v {
388 JsonVariant::Null => Value::Null,
389 JsonVariant::Bool(x) => Value::Boolean(x),
390 JsonVariant::Number(x) => match x {
391 JsonNumber::PosInt(i) => Value::UInt64(i),
392 JsonNumber::NegInt(i) => Value::Int64(i),
393 JsonNumber::Float(f) => Value::Float64(f),
394 },
395 JsonVariant::String(x) => Value::String(x.into()),
396 JsonVariant::Array(array) => {
397 let item_type = if let Some(first) = array.first() {
398 first.native_type()
399 } else {
400 JsonNativeType::Null
401 };
402 Value::List(ListValue::new(
403 array.into_iter().map(helper).collect(),
404 Arc::new((&item_type).into()),
405 ))
406 }
407 JsonVariant::Object(object) => {
408 let mut fields = Vec::with_capacity(object.len());
409 let mut items = Vec::with_capacity(object.len());
410 for (k, v) in object {
411 fields.push(StructField::new(k, (&v.native_type()).into(), true));
412 items.push(helper(v));
413 }
414 Value::Struct(StructValue::new(items, StructType::new(Arc::new(fields))))
415 }
416 JsonVariant::Variant(x) => Value::Binary(x.into()),
417 }
418 }
419 helper(self.json_variant)
420 }
421
422 pub(crate) fn try_align(&mut self, expected: &JsonType) -> Result<()> {
436 if self.json_type() == expected {
437 return Ok(());
438 }
439
440 fn helper(value: JsonVariant, expected: &JsonNativeType) -> Result<JsonVariant> {
441 Ok(match (value, expected) {
442 (JsonVariant::Null, _) | (_, JsonNativeType::Null) => JsonVariant::Null,
443 (JsonVariant::Bool(v), JsonNativeType::Bool) => JsonVariant::Bool(v),
444 (JsonVariant::Number(v), JsonNativeType::Number(n)) => {
445 return match n {
446 JsonNumberType::U64 => v
447 .as_u64()
448 .map(|x| JsonVariant::Number(JsonNumber::PosInt(x))),
449 JsonNumberType::I64 => v
450 .as_i64()
451 .map(|x| JsonVariant::Number(JsonNumber::NegInt(x))),
452 JsonNumberType::F64 => {
453 Some(JsonVariant::Number(JsonNumber::Float(v.as_f64().into())))
454 }
455 }
456 .with_context(|| AlignJsonValueSnafu {
457 reason: format!("unable to align number ‘{}’ to type {}", v, expected),
458 });
459 }
460 (JsonVariant::String(v), JsonNativeType::String) => JsonVariant::String(v),
461
462 (JsonVariant::Array(items), JsonNativeType::Array(expected)) => JsonVariant::Array(
463 items
464 .into_iter()
465 .map(|item| helper(item, expected.as_ref()))
466 .collect::<Result<_>>()?,
467 ),
468
469 (JsonVariant::Object(mut kvs), JsonNativeType::Object(expected)) => {
470 ensure!(
471 expected.keys().len() >= kvs.keys().len()
472 && kvs.keys().all(|k| expected.contains_key(k)),
473 AlignJsonValueSnafu {
474 reason: format!(
475 "aligned type '{}' should be superset of value '{}'",
476 JsonNativeType::Object(expected.clone()),
477 JsonVariant::from(kvs),
478 )
479 }
480 );
481
482 let mut object = BTreeMap::new();
483 for (field, field_type) in expected {
484 if let Some((k, v)) = kvs.remove_entry(field) {
485 object.insert(k, helper(v, field_type)?);
486 } else {
487 object.insert(field.clone(), JsonVariant::Null);
488 }
489 }
490 JsonVariant::Object(object)
491 }
492
493 (v, JsonNativeType::Variant) => {
494 let json: serde_json::Value =
495 JsonValue::new(v).try_into().context(SerializeSnafu)?;
496 serde_json::to_vec(&json)
497 .map(JsonVariant::Variant)
498 .context(SerializeSnafu)?
499 }
500
501 (value, expected) => {
502 return AlignJsonValueSnafu {
503 reason: format!(
504 "unable to align '{}' of type {} to type {}",
505 value,
506 value.native_type(),
507 expected,
508 ),
509 }
510 .fail();
511 }
512 })
513 }
514
515 let x = std::mem::take(&mut self.json_variant);
516 self.json_variant = helper(x, expected.native_type())?;
517 self.json_type = OnceLock::from(expected.clone());
518 Ok(())
519 }
520}
521
522impl<T: Into<JsonVariant>> From<T> for JsonValue {
523 fn from(v: T) -> Self {
524 Self {
525 json_type: OnceLock::new(),
526 json_variant: v.into(),
527 }
528 }
529}
530
531impl TryFrom<JsonValue> for serde_json::Value {
532 type Error = serde_json::Error;
533
534 fn try_from(v: JsonValue) -> serde_json::Result<Self> {
535 fn helper(v: JsonVariant) -> serde_json::Result<serde_json::Value> {
536 Ok(match v {
537 JsonVariant::Null => serde_json::Value::Null,
538 JsonVariant::Bool(x) => serde_json::Value::Bool(x),
539 JsonVariant::Number(x) => match x {
540 JsonNumber::PosInt(i) => serde_json::Value::Number(i.into()),
541 JsonNumber::NegInt(i) => serde_json::Value::Number(i.into()),
542 JsonNumber::Float(f) => {
543 if let Some(x) = Number::from_f64(f.0) {
544 serde_json::Value::Number(x)
545 } else {
546 serde_json::Value::String("NaN".into())
547 }
548 }
549 },
550 JsonVariant::String(x) => serde_json::Value::String(x),
551 JsonVariant::Array(array) => serde_json::Value::Array(
552 array
553 .into_iter()
554 .map(helper)
555 .collect::<serde_json::Result<Vec<_>>>()?,
556 ),
557 JsonVariant::Object(object) => {
558 let mut map = serde_json::Map::with_capacity(object.len());
559 for (k, v) in object {
560 map.insert(k, helper(v)?);
561 }
562 serde_json::Value::Object(map)
563 }
564 JsonVariant::Variant(x) => serde_json::from_slice(&x)?,
565 })
566 }
567 helper(v.json_variant)
568 }
569}
570
571impl Clone for JsonValue {
572 fn clone(&self) -> Self {
573 let Self {
574 json_type: _,
575 json_variant,
576 } = self;
577 Self {
578 json_type: OnceLock::new(),
579 json_variant: json_variant.clone(),
580 }
581 }
582}
583
584impl PartialEq<JsonValue> for JsonValue {
585 fn eq(&self, other: &JsonValue) -> bool {
586 let Self {
587 json_type: _,
588 json_variant,
589 } = self;
590 json_variant.eq(&other.json_variant)
591 }
592}
593
594impl Hash for JsonValue {
595 fn hash<H: Hasher>(&self, state: &mut H) {
596 let Self {
597 json_type: _,
598 json_variant,
599 } = self;
600 json_variant.hash(state);
601 }
602}
603
604impl Display for JsonValue {
605 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
606 write!(f, "{}", self.json_variant)
607 }
608}
609
610#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
612pub enum JsonVariantRef<'a> {
613 Null,
614 Bool(bool),
615 Number(JsonNumber),
616 String(&'a str),
617 Array(Vec<JsonVariantRef<'a>>),
618 Object(BTreeMap<&'a str, JsonVariantRef<'a>>),
619 Variant(&'a [u8]),
620}
621
622impl JsonVariantRef<'_> {
623 fn json_type(&self) -> JsonType {
624 fn native_type(v: &JsonVariantRef<'_>) -> JsonNativeType {
625 match v {
626 JsonVariantRef::Null => JsonNativeType::Null,
627 JsonVariantRef::Bool(_) => JsonNativeType::Bool,
628 JsonVariantRef::Number(n) => match n {
629 JsonNumber::PosInt(_) => JsonNativeType::u64(),
630 JsonNumber::NegInt(_) => JsonNativeType::i64(),
631 JsonNumber::Float(_) => JsonNativeType::f64(),
632 },
633 JsonVariantRef::String(_) => JsonNativeType::String,
634 JsonVariantRef::Array(array) => {
635 let item_type = if let Some(first) = array.first() {
636 native_type(first)
637 } else {
638 JsonNativeType::Null
639 };
640 JsonNativeType::Array(Box::new(item_type))
641 }
642 JsonVariantRef::Object(object) => JsonNativeType::Object(
643 object
644 .iter()
645 .map(|(k, v)| (k.to_string(), native_type(v)))
646 .collect(),
647 ),
648 JsonVariantRef::Variant(_) => JsonNativeType::Variant,
649 }
650 }
651 JsonType::new_json2(native_type(self))
652 }
653}
654
655impl From<()> for JsonVariantRef<'_> {
656 fn from(_: ()) -> Self {
657 Self::Null
658 }
659}
660
661impl From<bool> for JsonVariantRef<'_> {
662 fn from(v: bool) -> Self {
663 Self::Bool(v)
664 }
665}
666
667impl<T: Into<JsonNumber>> From<T> for JsonVariantRef<'_> {
668 fn from(v: T) -> Self {
669 Self::Number(v.into())
670 }
671}
672
673impl<'a> From<&'a str> for JsonVariantRef<'a> {
674 fn from(v: &'a str) -> Self {
675 Self::String(v)
676 }
677}
678
679impl<'a, const N: usize, T: Into<JsonVariantRef<'a>>> From<[T; N]> for JsonVariantRef<'a> {
680 fn from(vs: [T; N]) -> Self {
681 Self::Array(vs.into_iter().map(|x| x.into()).collect())
682 }
683}
684
685impl<'a, V: Into<JsonVariantRef<'a>>, const N: usize> From<[(&'a str, V); N]>
686 for JsonVariantRef<'a>
687{
688 fn from(vs: [(&'a str, V); N]) -> Self {
689 Self::Object(vs.into_iter().map(|(k, v)| (k, v.into())).collect())
690 }
691}
692
693impl<'a> From<Vec<JsonVariantRef<'a>>> for JsonVariantRef<'a> {
694 fn from(v: Vec<JsonVariantRef<'a>>) -> Self {
695 Self::Array(v)
696 }
697}
698
699impl<'a> From<BTreeMap<&'a str, JsonVariantRef<'a>>> for JsonVariantRef<'a> {
700 fn from(v: BTreeMap<&'a str, JsonVariantRef<'a>>) -> Self {
701 Self::Object(v)
702 }
703}
704
705impl From<JsonVariantRef<'_>> for JsonVariant {
706 fn from(v: JsonVariantRef) -> Self {
707 match v {
708 JsonVariantRef::Null => Self::Null,
709 JsonVariantRef::Bool(x) => Self::Bool(x),
710 JsonVariantRef::Number(x) => Self::Number(x),
711 JsonVariantRef::String(x) => Self::String(x.to_string()),
712 JsonVariantRef::Array(array) => {
713 Self::Array(array.into_iter().map(Into::into).collect())
714 }
715 JsonVariantRef::Object(object) => Self::Object(
716 object
717 .into_iter()
718 .map(|(k, v)| (k.to_string(), v.into()))
719 .collect(),
720 ),
721 JsonVariantRef::Variant(x) => Self::Variant(x.to_vec()),
722 }
723 }
724}
725
726impl<'a> From<&'a [u8]> for JsonVariantRef<'a> {
727 fn from(value: &'a [u8]) -> Self {
728 Self::Variant(value)
729 }
730}
731
732#[derive(Debug, Serialize)]
734pub struct JsonValueRef<'a> {
735 #[serde(skip)]
736 json_type: OnceLock<JsonType>,
737 json_variant: JsonVariantRef<'a>,
738}
739
740impl<'a> JsonValueRef<'a> {
741 pub fn null() -> Self {
742 ().into()
743 }
744
745 pub(crate) fn data_type(&self) -> ConcreteDataType {
746 ConcreteDataType::Json(self.json_type().clone())
747 }
748
749 pub(crate) fn json_type(&self) -> &JsonType {
750 self.json_type.get_or_init(|| self.json_variant.json_type())
751 }
752
753 pub fn into_variant(self) -> JsonVariantRef<'a> {
754 self.json_variant
755 }
756
757 pub(crate) fn is_null(&self) -> bool {
758 matches!(self.json_variant, JsonVariantRef::Null)
759 }
760
761 pub fn is_object(&self) -> bool {
762 matches!(self.json_variant, JsonVariantRef::Object(_))
763 }
764
765 pub(crate) fn as_f32(&self) -> Option<f32> {
766 match self.json_variant {
767 JsonVariantRef::Number(JsonNumber::Float(f)) => f.to_f32(),
768 _ => None,
769 }
770 }
771
772 pub(crate) fn as_f64(&self) -> Option<f64> {
773 match self.json_variant {
774 JsonVariantRef::Number(JsonNumber::Float(f)) => Some(f.0),
775 _ => None,
776 }
777 }
778
779 fn as_value_ref(&self) -> ValueRef<'_> {
780 fn helper<'a>(v: &'a JsonVariantRef) -> ValueRef<'a> {
781 match v {
782 JsonVariantRef::Null => ValueRef::Null,
783 JsonVariantRef::Bool(x) => ValueRef::Boolean(*x),
784 JsonVariantRef::Number(x) => match x {
785 JsonNumber::PosInt(i) => ValueRef::UInt64(*i),
786 JsonNumber::NegInt(i) => ValueRef::Int64(*i),
787 JsonNumber::Float(f) => ValueRef::Float64(*f),
788 },
789 JsonVariantRef::String(x) => ValueRef::String(x),
790 JsonVariantRef::Array(array) => {
791 let val = array.iter().map(helper).collect::<Vec<_>>();
792 let item_datatype = if let Some(first) = val.first() {
793 first.data_type()
794 } else {
795 ConcreteDataType::null_datatype()
796 };
797 ValueRef::List(ListValueRef::RefList {
798 val,
799 item_datatype: Arc::new(item_datatype),
800 })
801 }
802 JsonVariantRef::Object(object) => {
803 let mut fields = Vec::with_capacity(object.len());
804 let mut val = Vec::with_capacity(object.len());
805 for (k, v) in object.iter() {
806 let v = helper(v);
807 fields.push(StructField::new(k.to_string(), v.data_type(), true));
808 val.push(v);
809 }
810 ValueRef::Struct(StructValueRef::RefList {
811 val,
812 fields: StructType::new(Arc::new(fields)),
813 })
814 }
815 JsonVariantRef::Variant(x) => ValueRef::Binary(x),
816 }
817 }
818 helper(&self.json_variant)
819 }
820
821 pub(crate) fn data_size(&self) -> usize {
822 size_of_val(self)
823 }
824
825 pub(crate) fn variant(&self) -> &JsonVariantRef<'a> {
826 &self.json_variant
827 }
828
829 pub(crate) fn as_struct_value(&self) -> ValueRef<'_> {
830 if self.is_object() {
831 return self.as_value_ref();
832 }
833
834 ValueRef::Struct(StructValueRef::RefList {
835 val: vec![self.as_value_ref()],
836 fields: self.json_type().as_struct_type(),
837 })
838 }
839}
840
841impl<'a, T: Into<JsonVariantRef<'a>>> From<T> for JsonValueRef<'a> {
842 fn from(v: T) -> Self {
843 Self {
844 json_type: OnceLock::new(),
845 json_variant: v.into(),
846 }
847 }
848}
849
850impl From<JsonValueRef<'_>> for JsonValue {
851 fn from(v: JsonValueRef<'_>) -> Self {
852 Self {
853 json_type: OnceLock::new(),
854 json_variant: v.json_variant.into(),
855 }
856 }
857}
858
859impl PartialEq for JsonValueRef<'_> {
860 fn eq(&self, other: &Self) -> bool {
861 let Self {
862 json_type: _,
863 json_variant,
864 } = self;
865 json_variant == &other.json_variant
866 }
867}
868
869impl Eq for JsonValueRef<'_> {}
870
871impl Clone for JsonValueRef<'_> {
872 fn clone(&self) -> Self {
873 let Self {
874 json_type: _,
875 json_variant,
876 } = self;
877 Self {
878 json_type: OnceLock::new(),
879 json_variant: json_variant.clone(),
880 }
881 }
882}
883
884#[cfg(test)]
885mod tests {
886 use super::*;
887 use crate::types::json_type::JsonObjectType;
888
889 #[test]
890 fn test_align_json_value() -> Result<()> {
891 fn parse_json_value(json: &str) -> JsonValue {
892 let value: serde_json::Value = serde_json::from_str(json).unwrap();
893 value.into()
894 }
895
896 let mut value = JsonValue::from(true);
898 assert_eq!(
899 value.json_type(),
900 &JsonType::new_json2(JsonNativeType::Bool)
901 );
902 value.try_align(&JsonType::null())?;
903 assert_eq!(value, JsonValue::null());
904 assert_eq!(value.json_type(), &JsonType::null());
905
906 let expected = JsonType::new_json2(JsonNativeType::Object(JsonObjectType::from([
909 ("extra".to_string(), JsonNativeType::u64()),
910 (
911 "items".to_string(),
912 JsonNativeType::Array(Box::new(JsonNativeType::Object(JsonObjectType::from([
913 ("id".to_string(), JsonNativeType::u64()),
914 ("payload".to_string(), JsonNativeType::Variant),
915 ("note".to_string(), JsonNativeType::String),
916 ])))),
917 ),
918 ("name".to_string(), JsonNativeType::String),
919 ])));
920 let mut value = parse_json_value(r#"{"items":[{"id":1,"payload":{"k":"v"}}],"extra":1}"#);
921 assert_ne!(value.json_type(), &expected);
922 value.try_align(&expected)?;
923 assert_eq!(
924 value,
925 JsonValue::from(JsonVariant::Object(BTreeMap::from([
926 ("extra".to_string(), JsonVariant::from(1_u64)),
927 (
928 "items".to_string(),
929 JsonVariant::Array(vec![JsonVariant::Object(BTreeMap::from([
930 ("id".to_string(), JsonVariant::from(1_u64)),
931 ("note".to_string(), JsonVariant::Null),
932 (
933 "payload".to_string(),
934 JsonVariant::Variant(br#"{"k":"v"}"#.to_vec()),
935 ),
936 ]))]),
937 ),
938 ("name".to_string(), JsonVariant::Null),
939 ])))
940 );
941 assert_eq!(value.json_type(), &expected);
942
943 let expected = JsonType::new_json2(JsonNativeType::Object(JsonObjectType::from([(
945 "items".to_string(),
946 JsonNativeType::Array(Box::new(JsonNativeType::Object(JsonObjectType::from([
947 ("id".to_string(), JsonNativeType::u64()),
948 ("payload".to_string(), JsonNativeType::Variant),
949 ])))),
950 )])));
951 let mut value =
952 parse_json_value(r#"{"items":[{"id":1,"payload":{"k":"v"},"extra":true}]}"#);
953 let err = value.try_align(&expected).unwrap_err();
954 assert_eq!(
955 err.to_string(),
956 r#"Failed to align JSON value, reason: aligned type '{"id":"<Number>","payload":"<Variant>"}' should be superset of value '{ extra: true, id: 1, payload: { k: v } }'"#
957 );
958
959 let mut value = parse_json_value(r#"{"foo":[1,true,null]}"#);
961 value.try_align(&JsonType::new_json2(JsonNativeType::Variant))?;
962 assert_eq!(
963 value,
964 JsonValue::from(JsonVariant::Variant(br#"{"foo":[1,true,null]}"#.to_vec()))
965 );
966
967 let mut value = JsonValue::from("hello");
969 let err = value
970 .try_align(&JsonType::new_json2(JsonNativeType::Bool))
971 .unwrap_err();
972 assert_eq!(
973 err.to_string(),
974 r#"Failed to align JSON value, reason: unable to align 'hello' of type "<String>" to type "<Bool>""#
975 );
976
977 Ok(())
978 }
979}