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