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 fn native_type(&self) -> JsonNativeType {
70 match self {
71 JsonNumber::PosInt(_) => JsonNativeType::u64(),
72 JsonNumber::NegInt(_) => JsonNativeType::i64(),
73 JsonNumber::Float(_) => JsonNativeType::f64(),
74 }
75 }
76}
77
78impl From<u64> for JsonNumber {
79 fn from(i: u64) -> Self {
80 Self::PosInt(i)
81 }
82}
83
84impl From<i64> for JsonNumber {
85 fn from(n: i64) -> Self {
86 Self::NegInt(n)
87 }
88}
89
90impl From<f64> for JsonNumber {
91 fn from(i: f64) -> Self {
92 Self::Float(i.into())
93 }
94}
95
96impl From<Number> for JsonNumber {
97 fn from(n: Number) -> Self {
98 if let Some(i) = n.as_i64() {
99 i.into()
100 } else if let Some(i) = n.as_u64() {
101 i.into()
102 } else {
103 n.as_f64().unwrap_or(f64::NAN).into()
104 }
105 }
106}
107
108impl Display for JsonNumber {
109 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
110 match self {
111 Self::PosInt(x) => write!(f, "{x}"),
112 Self::NegInt(x) => write!(f, "{x}"),
113 Self::Float(x) => write!(f, "{x}"),
114 }
115 }
116}
117
118#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
120pub enum JsonVariant {
121 #[default]
122 Null,
123 Bool(bool),
124 Number(JsonNumber),
125 String(String),
126 Array(Vec<JsonVariant>),
127 Object(BTreeMap<String, JsonVariant>),
128 Variant(Vec<u8>),
130}
131
132impl JsonVariant {
133 pub(crate) fn as_i64(&self) -> Option<i64> {
134 match self {
135 JsonVariant::Number(n) => n.as_i64(),
136 _ => None,
137 }
138 }
139
140 pub(crate) fn as_u64(&self) -> Option<u64> {
141 match self {
142 JsonVariant::Number(n) => n.as_u64(),
143 _ => None,
144 }
145 }
146
147 pub(crate) fn as_f64(&self) -> Option<f64> {
148 match self {
149 JsonVariant::Number(n) => Some(n.as_f64()),
150 _ => None,
151 }
152 }
153
154 pub(crate) fn native_type(&self) -> JsonNativeType {
155 match self {
156 JsonVariant::Null => JsonNativeType::Null,
157 JsonVariant::Bool(_) => JsonNativeType::Bool,
158 JsonVariant::Number(n) => n.native_type(),
159 JsonVariant::String(_) => JsonNativeType::String,
160 JsonVariant::Array(array) => {
161 json_array_native_type(array.iter().map(JsonVariant::native_type))
162 }
163 JsonVariant::Object(object) => {
164 json_object_native_type(object.iter().map(|(k, v)| (k, v.native_type())))
165 }
166 JsonVariant::Variant(_) => JsonNativeType::Variant,
167 }
168 }
169
170 fn json_type(&self) -> JsonType {
171 JsonType::new_json2(self.native_type())
172 }
173
174 fn as_ref(&self) -> JsonVariantRef<'_> {
175 match self {
176 JsonVariant::Null => JsonVariantRef::Null,
177 JsonVariant::Bool(x) => (*x).into(),
178 JsonVariant::Number(x) => match x {
179 JsonNumber::PosInt(i) => (*i).into(),
180 JsonNumber::NegInt(i) => (*i).into(),
181 JsonNumber::Float(f) => (f.0).into(),
182 },
183 JsonVariant::String(x) => x.as_str().into(),
184 JsonVariant::Array(array) => {
185 JsonVariantRef::Array(array.iter().map(|x| x.as_ref()).collect())
186 }
187 JsonVariant::Object(object) => JsonVariantRef::Object(
188 object
189 .iter()
190 .map(|(k, v)| (k.as_str(), v.as_ref()))
191 .collect(),
192 ),
193 JsonVariant::Variant(v) => JsonVariantRef::Variant(v),
194 }
195 }
196}
197
198impl From<()> for JsonVariant {
199 fn from(_: ()) -> Self {
200 Self::Null
201 }
202}
203
204impl From<bool> for JsonVariant {
205 fn from(v: bool) -> Self {
206 Self::Bool(v)
207 }
208}
209
210impl<T: Into<JsonNumber>> From<T> for JsonVariant {
211 fn from(v: T) -> Self {
212 Self::Number(v.into())
213 }
214}
215
216impl From<&str> for JsonVariant {
217 fn from(v: &str) -> Self {
218 Self::String(v.to_string())
219 }
220}
221
222impl From<String> for JsonVariant {
223 fn from(v: String) -> Self {
224 Self::String(v)
225 }
226}
227
228impl<const N: usize, T: Into<JsonVariant>> From<[T; N]> for JsonVariant {
229 fn from(vs: [T; N]) -> Self {
230 Self::Array(vs.into_iter().map(|x| x.into()).collect())
231 }
232}
233
234impl<K: Into<String>, V: Into<JsonVariant>, const N: usize> From<[(K, V); N]> for JsonVariant {
235 fn from(vs: [(K, V); N]) -> Self {
236 Self::Object(vs.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
237 }
238}
239
240impl From<serde_json::Value> for JsonVariant {
241 fn from(v: serde_json::Value) -> Self {
242 fn helper(v: serde_json::Value) -> JsonVariant {
243 match v {
244 serde_json::Value::Null => JsonVariant::Null,
245 serde_json::Value::Bool(b) => b.into(),
246 serde_json::Value::Number(n) => n.into(),
247 serde_json::Value::String(s) => s.into(),
248 serde_json::Value::Array(array) => {
249 JsonVariant::Array(array.into_iter().map(helper).collect())
250 }
251 serde_json::Value::Object(object) => {
252 JsonVariant::Object(object.into_iter().map(|(k, v)| (k, helper(v))).collect())
253 }
254 }
255 }
256 helper(v)
257 }
258}
259
260impl From<BTreeMap<String, JsonVariant>> for JsonVariant {
261 fn from(v: BTreeMap<String, JsonVariant>) -> Self {
262 Self::Object(v)
263 }
264}
265
266impl Display for JsonVariant {
267 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
268 match self {
269 Self::Null => write!(f, "null"),
270 Self::Bool(x) => write!(f, "{x}"),
271 Self::Number(x) => write!(f, "{x}"),
272 Self::String(x) => write!(f, "{x}"),
273 Self::Array(array) => write!(
274 f,
275 "[{}]",
276 array
277 .iter()
278 .map(|x| x.to_string())
279 .collect::<Vec<_>>()
280 .join(", ")
281 ),
282 Self::Object(object) => {
283 write!(
284 f,
285 "{{ {} }}",
286 object
287 .iter()
288 .map(|(k, v)| format!("{k}: {v}"))
289 .collect::<Vec<_>>()
290 .join(", ")
291 )
292 }
293 Self::Variant(x) => {
294 let result: serde_json::Result<serde_json::Value> = serde_json::from_slice(x);
295 match result {
296 Ok(v) => write!(f, "{v}"),
297 Err(_) => write!(f, "{x:?}"),
298 }
299 }
300 }
301 }
302}
303
304#[derive(Debug, Eq, Serialize, Deserialize)]
306pub struct JsonValue {
307 #[serde(skip)]
308 json_type: OnceLock<JsonType>,
309 json_variant: JsonVariant,
310}
311
312impl JsonValue {
313 pub fn null() -> Self {
314 ().into()
315 }
316
317 pub(crate) fn new(json_variant: JsonVariant) -> Self {
318 Self {
319 json_type: OnceLock::new(),
320 json_variant,
321 }
322 }
323
324 pub(crate) fn data_type(&self) -> ConcreteDataType {
325 ConcreteDataType::Json(self.json_type().clone())
326 }
327
328 pub fn json_type(&self) -> &JsonType {
329 self.json_type.get_or_init(|| self.json_variant.json_type())
330 }
331
332 pub(crate) fn is_null(&self) -> bool {
333 matches!(self.json_variant, JsonVariant::Null)
334 }
335
336 pub fn is_empty_object(&self) -> bool {
338 match &self.json_variant {
339 JsonVariant::Object(object) => object.is_empty(),
340 _ => false,
341 }
342 }
343
344 pub(crate) fn as_i64(&self) -> Option<i64> {
345 self.json_variant.as_i64()
346 }
347
348 pub(crate) fn as_u64(&self) -> Option<u64> {
349 self.json_variant.as_u64()
350 }
351
352 pub(crate) fn as_f64_lossy(&self) -> Option<f64> {
353 match self.json_variant {
354 JsonVariant::Number(n) => Some(match n {
355 JsonNumber::PosInt(i) => i as f64,
356 JsonNumber::NegInt(i) => i as f64,
357 JsonNumber::Float(f) => f.0,
358 }),
359 _ => None,
360 }
361 }
362
363 pub(crate) fn as_bool(&self) -> Option<bool> {
364 match self.json_variant {
365 JsonVariant::Bool(b) => Some(b),
366 _ => None,
367 }
368 }
369
370 pub fn as_ref(&self) -> JsonValueRef<'_> {
371 JsonValueRef {
372 json_type: OnceLock::new(),
373 json_variant: self.json_variant.as_ref(),
374 }
375 }
376
377 pub fn into_variant(self) -> JsonVariant {
378 self.json_variant
379 }
380
381 pub(crate) fn into_value(self) -> Value {
382 fn helper(v: JsonVariant) -> Value {
383 match v {
384 JsonVariant::Null => Value::Null,
385 JsonVariant::Bool(x) => Value::Boolean(x),
386 JsonVariant::Number(x) => match x {
387 JsonNumber::PosInt(i) => Value::UInt64(i),
388 JsonNumber::NegInt(i) => Value::Int64(i),
389 JsonNumber::Float(f) => Value::Float64(f),
390 },
391 JsonVariant::String(x) => Value::String(x.into()),
392 JsonVariant::Array(array) => {
393 let values = array.into_iter().map(helper).collect::<Vec<_>>();
394 debug_assert!(
395 values
396 .windows(2)
397 .all(|w| w[0].data_type() == w[1].data_type())
398 );
399 let item_type = values
400 .first()
401 .map(|x| x.data_type())
402 .unwrap_or_else(ConcreteDataType::null_datatype);
403 Value::List(ListValue::new(values, Arc::new(item_type)))
404 }
405 JsonVariant::Object(object) => {
406 let mut fields = Vec::with_capacity(object.len());
407 let mut items = Vec::with_capacity(object.len());
408 for (k, v) in object {
409 let v = helper(v);
410 fields.push(StructField::new(k, v.data_type(), true));
411 items.push(v);
412 }
413 Value::Struct(StructValue::new(items, StructType::new(Arc::new(fields))))
414 }
415 JsonVariant::Variant(x) => Value::Binary(x.into()),
416 }
417 }
418 helper(self.json_variant)
419 }
420
421 pub(crate) fn try_align(&mut self, expected: &JsonType) -> Result<()> {
435 if self.json_type() == expected {
436 return Ok(());
437 }
438
439 fn helper(value: JsonVariant, expected: &JsonNativeType) -> Result<JsonVariant> {
440 Ok(match (value, expected) {
441 (JsonVariant::Null, _) | (_, JsonNativeType::Null) => JsonVariant::Null,
442 (JsonVariant::Bool(v), JsonNativeType::Bool) => JsonVariant::Bool(v),
443 (JsonVariant::Number(v), JsonNativeType::Number(n)) => {
444 return match n {
445 JsonNumberType::U64 => v
446 .as_u64()
447 .map(|x| JsonVariant::Number(JsonNumber::PosInt(x))),
448 JsonNumberType::I64 => v
449 .as_i64()
450 .map(|x| JsonVariant::Number(JsonNumber::NegInt(x))),
451 JsonNumberType::F64 => {
452 Some(JsonVariant::Number(JsonNumber::Float(v.as_f64().into())))
453 }
454 }
455 .with_context(|| AlignJsonValueSnafu {
456 reason: format!("unable to align number ‘{}’ to type {}", v, expected),
457 });
458 }
459 (JsonVariant::String(v), JsonNativeType::String) => JsonVariant::String(v),
460
461 (JsonVariant::Array(items), JsonNativeType::Array(expected)) => JsonVariant::Array(
462 items
463 .into_iter()
464 .map(|item| helper(item, expected.as_ref()))
465 .collect::<Result<_>>()?,
466 ),
467
468 (JsonVariant::Object(kvs), _) if kvs.is_empty() => JsonVariant::Null,
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::new();
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 native_type(&self) -> JsonNativeType {
624 match self {
625 JsonVariantRef::Null => JsonNativeType::Null,
626 JsonVariantRef::Bool(_) => JsonNativeType::Bool,
627 JsonVariantRef::Number(n) => n.native_type(),
628 JsonVariantRef::String(_) => JsonNativeType::String,
629 JsonVariantRef::Array(array) => {
630 json_array_native_type(array.iter().map(JsonVariantRef::native_type))
631 }
632 JsonVariantRef::Object(object) => {
633 json_object_native_type(object.iter().map(|(k, v)| (*k, v.native_type())))
634 }
635 JsonVariantRef::Variant(_) => JsonNativeType::Variant,
636 }
637 }
638
639 fn json_type(&self) -> JsonType {
640 JsonType::new_json2(self.native_type())
641 }
642}
643
644fn json_array_native_type<I>(items: I) -> JsonNativeType
645where
646 I: IntoIterator<Item = JsonNativeType>,
647{
648 let mut iter = items.into_iter();
649 let mut item_type = match iter.next() {
650 Some(t) => t,
651 None => return JsonNativeType::Array(Box::new(JsonNativeType::Null)),
652 };
653 for x in iter {
654 if matches!(item_type, JsonNativeType::Variant) {
655 break;
656 }
657 item_type.merge(&x);
658 }
659 JsonNativeType::Array(Box::new(item_type))
660}
661
662fn json_object_native_type<I, K>(fields: I) -> JsonNativeType
663where
664 I: IntoIterator<Item = (K, JsonNativeType)>,
665 K: Into<String>,
666{
667 let mut fields = fields.into_iter().peekable();
668 if fields.peek().is_none() {
669 JsonNativeType::Null
670 } else {
671 JsonNativeType::Object(fields.map(|(k, v)| (k.into(), v)).collect())
672 }
673}
674
675impl From<()> for JsonVariantRef<'_> {
676 fn from(_: ()) -> Self {
677 Self::Null
678 }
679}
680
681impl From<bool> for JsonVariantRef<'_> {
682 fn from(v: bool) -> Self {
683 Self::Bool(v)
684 }
685}
686
687impl<T: Into<JsonNumber>> From<T> for JsonVariantRef<'_> {
688 fn from(v: T) -> Self {
689 Self::Number(v.into())
690 }
691}
692
693impl<'a> From<&'a str> for JsonVariantRef<'a> {
694 fn from(v: &'a str) -> Self {
695 Self::String(v)
696 }
697}
698
699impl<'a, const N: usize, T: Into<JsonVariantRef<'a>>> From<[T; N]> for JsonVariantRef<'a> {
700 fn from(vs: [T; N]) -> Self {
701 Self::Array(vs.into_iter().map(|x| x.into()).collect())
702 }
703}
704
705impl<'a, V: Into<JsonVariantRef<'a>>, const N: usize> From<[(&'a str, V); N]>
706 for JsonVariantRef<'a>
707{
708 fn from(vs: [(&'a str, V); N]) -> Self {
709 Self::Object(vs.into_iter().map(|(k, v)| (k, v.into())).collect())
710 }
711}
712
713impl<'a> From<Vec<JsonVariantRef<'a>>> for JsonVariantRef<'a> {
714 fn from(v: Vec<JsonVariantRef<'a>>) -> Self {
715 Self::Array(v)
716 }
717}
718
719impl<'a> From<BTreeMap<&'a str, JsonVariantRef<'a>>> for JsonVariantRef<'a> {
720 fn from(v: BTreeMap<&'a str, JsonVariantRef<'a>>) -> Self {
721 Self::Object(v)
722 }
723}
724
725impl From<JsonVariantRef<'_>> for JsonVariant {
726 fn from(v: JsonVariantRef) -> Self {
727 match v {
728 JsonVariantRef::Null => Self::Null,
729 JsonVariantRef::Bool(x) => Self::Bool(x),
730 JsonVariantRef::Number(x) => Self::Number(x),
731 JsonVariantRef::String(x) => Self::String(x.to_string()),
732 JsonVariantRef::Array(array) => {
733 Self::Array(array.into_iter().map(Into::into).collect())
734 }
735 JsonVariantRef::Object(object) => Self::Object(
736 object
737 .into_iter()
738 .map(|(k, v)| (k.to_string(), v.into()))
739 .collect(),
740 ),
741 JsonVariantRef::Variant(x) => Self::Variant(x.to_vec()),
742 }
743 }
744}
745
746impl<'a> From<&'a [u8]> for JsonVariantRef<'a> {
747 fn from(value: &'a [u8]) -> Self {
748 Self::Variant(value)
749 }
750}
751
752#[derive(Debug, Serialize)]
754pub struct JsonValueRef<'a> {
755 #[serde(skip)]
756 json_type: OnceLock<JsonType>,
757 json_variant: JsonVariantRef<'a>,
758}
759
760impl<'a> JsonValueRef<'a> {
761 pub fn null() -> Self {
762 ().into()
763 }
764
765 pub(crate) fn data_type(&self) -> ConcreteDataType {
766 ConcreteDataType::Json(self.json_type().clone())
767 }
768
769 pub(crate) fn json_type(&self) -> &JsonType {
770 self.json_type.get_or_init(|| self.json_variant.json_type())
771 }
772
773 pub fn into_variant(self) -> JsonVariantRef<'a> {
774 self.json_variant
775 }
776
777 pub(crate) fn is_null(&self) -> bool {
778 matches!(self.json_variant, JsonVariantRef::Null)
779 }
780
781 pub fn is_object(&self) -> bool {
782 matches!(self.json_variant, JsonVariantRef::Object(_))
783 }
784
785 pub(crate) fn as_f32(&self) -> Option<f32> {
786 match self.json_variant {
787 JsonVariantRef::Number(JsonNumber::Float(f)) => f.to_f32(),
788 _ => None,
789 }
790 }
791
792 pub(crate) fn as_f64(&self) -> Option<f64> {
793 match self.json_variant {
794 JsonVariantRef::Number(JsonNumber::Float(f)) => Some(f.0),
795 _ => None,
796 }
797 }
798
799 fn as_value_ref(&self) -> ValueRef<'_> {
800 fn helper<'a>(v: &'a JsonVariantRef) -> ValueRef<'a> {
801 match v {
802 JsonVariantRef::Null => ValueRef::Null,
803 JsonVariantRef::Bool(x) => ValueRef::Boolean(*x),
804 JsonVariantRef::Number(x) => match x {
805 JsonNumber::PosInt(i) => ValueRef::UInt64(*i),
806 JsonNumber::NegInt(i) => ValueRef::Int64(*i),
807 JsonNumber::Float(f) => ValueRef::Float64(*f),
808 },
809 JsonVariantRef::String(x) => ValueRef::String(x),
810 JsonVariantRef::Array(array) => {
811 let val = array.iter().map(helper).collect::<Vec<_>>();
812 let item_datatype = if let Some(first) = val.first() {
813 first.data_type()
814 } else {
815 ConcreteDataType::null_datatype()
816 };
817 ValueRef::List(ListValueRef::RefList {
818 val,
819 item_datatype: Arc::new(item_datatype),
820 })
821 }
822 JsonVariantRef::Object(object) => {
823 let mut fields = Vec::with_capacity(object.len());
824 let mut val = Vec::with_capacity(object.len());
825 for (k, v) in object.iter() {
826 let v = helper(v);
827 fields.push(StructField::new(k.to_string(), v.data_type(), true));
828 val.push(v);
829 }
830 ValueRef::Struct(StructValueRef::RefList {
831 val,
832 fields: StructType::new(Arc::new(fields)),
833 })
834 }
835 JsonVariantRef::Variant(x) => ValueRef::Binary(x),
836 }
837 }
838 helper(&self.json_variant)
839 }
840
841 pub(crate) fn data_size(&self) -> usize {
842 size_of_val(self)
843 }
844
845 pub(crate) fn variant(&self) -> &JsonVariantRef<'a> {
846 &self.json_variant
847 }
848
849 pub(crate) fn as_struct_value(&self) -> ValueRef<'_> {
850 if self.is_object() {
851 return self.as_value_ref();
852 }
853
854 ValueRef::Struct(StructValueRef::RefList {
855 val: vec![self.as_value_ref()],
856 fields: self.json_type().as_struct_type(),
857 })
858 }
859}
860
861impl<'a, T: Into<JsonVariantRef<'a>>> From<T> for JsonValueRef<'a> {
862 fn from(v: T) -> Self {
863 Self {
864 json_type: OnceLock::new(),
865 json_variant: v.into(),
866 }
867 }
868}
869
870impl From<JsonValueRef<'_>> for JsonValue {
871 fn from(v: JsonValueRef<'_>) -> Self {
872 Self {
873 json_type: OnceLock::new(),
874 json_variant: v.json_variant.into(),
875 }
876 }
877}
878
879impl PartialEq for JsonValueRef<'_> {
880 fn eq(&self, other: &Self) -> bool {
881 let Self {
882 json_type: _,
883 json_variant,
884 } = self;
885 json_variant == &other.json_variant
886 }
887}
888
889impl Eq for JsonValueRef<'_> {}
890
891impl Clone for JsonValueRef<'_> {
892 fn clone(&self) -> Self {
893 let Self {
894 json_type: _,
895 json_variant,
896 } = self;
897 Self {
898 json_type: OnceLock::new(),
899 json_variant: json_variant.clone(),
900 }
901 }
902}
903
904#[cfg(test)]
905mod tests {
906 use super::*;
907 use crate::types::json_type::JsonObjectType;
908
909 #[test]
910 fn test_align_json_value() -> Result<()> {
911 fn parse_json_value(json: &str) -> JsonValue {
912 let value: serde_json::Value = serde_json::from_str(json).unwrap();
913 value.into()
914 }
915
916 let mut value = JsonValue::from(true);
918 assert_eq!(
919 value.json_type(),
920 &JsonType::new_json2(JsonNativeType::Bool)
921 );
922 value.try_align(&JsonType::null())?;
923 assert_eq!(value, JsonValue::null());
924 assert_eq!(value.json_type(), &JsonType::null());
925
926 let expected = JsonType::new_json2(JsonNativeType::Object(JsonObjectType::from([
929 ("extra".to_string(), JsonNativeType::u64()),
930 (
931 "items".to_string(),
932 JsonNativeType::Array(Box::new(JsonNativeType::Object(JsonObjectType::from([
933 ("id".to_string(), JsonNativeType::u64()),
934 ("payload".to_string(), JsonNativeType::Variant),
935 ("note".to_string(), JsonNativeType::String),
936 ])))),
937 ),
938 ("name".to_string(), JsonNativeType::String),
939 ])));
940 let mut value = parse_json_value(r#"{"items":[{"id":1,"payload":{"k":"v"}}],"extra":1}"#);
941 assert_ne!(value.json_type(), &expected);
942 value.try_align(&expected)?;
943 assert_eq!(
944 value,
945 JsonValue::from(JsonVariant::Object(BTreeMap::from([
946 ("extra".to_string(), JsonVariant::from(1_u64)),
947 (
948 "items".to_string(),
949 JsonVariant::Array(vec![JsonVariant::Object(BTreeMap::from([
950 ("id".to_string(), JsonVariant::from(1_u64)),
951 ("note".to_string(), JsonVariant::Null),
952 (
953 "payload".to_string(),
954 JsonVariant::Variant(br#"{"k":"v"}"#.to_vec()),
955 ),
956 ]))]),
957 ),
958 ("name".to_string(), JsonVariant::Null),
959 ])))
960 );
961
962 let expected = JsonType::new_json2(JsonNativeType::Object(JsonObjectType::from([(
964 "items".to_string(),
965 JsonNativeType::Array(Box::new(JsonNativeType::Object(JsonObjectType::from([
966 ("id".to_string(), JsonNativeType::u64()),
967 ("payload".to_string(), JsonNativeType::Variant),
968 ])))),
969 )])));
970 let mut value =
971 parse_json_value(r#"{"items":[{"id":1,"payload":{"k":"v"},"extra":true}]}"#);
972 let err = value.try_align(&expected).unwrap_err();
973 assert_eq!(
974 err.to_string(),
975 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 } }'"#
976 );
977
978 let mut value = parse_json_value(r#"{"foo":[1,true,null]}"#);
980 value.try_align(&JsonType::new_json2(JsonNativeType::Variant))?;
981 assert_eq!(
982 value,
983 JsonValue::from(JsonVariant::Variant(br#"{"foo":[1,true,null]}"#.to_vec()))
984 );
985
986 let mut value = JsonValue::from("hello");
988 let err = value
989 .try_align(&JsonType::new_json2(JsonNativeType::Bool))
990 .unwrap_err();
991 assert_eq!(
992 err.to_string(),
993 r#"Failed to align JSON value, reason: unable to align 'hello' of type "<String>" to type "<Bool>""#
994 );
995
996 Ok(())
997 }
998}