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