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 fn contains_empty_object(&self) -> bool {
166 match self {
167 JsonVariant::Array(array) => array.iter().any(JsonVariant::contains_empty_object),
168 JsonVariant::Object(object) => {
169 object.is_empty() || object.values().any(JsonVariant::contains_empty_object)
170 }
171 _ => false,
172 }
173 }
174
175 fn as_ref(&self) -> JsonVariantRef<'_> {
176 match self {
177 JsonVariant::Null => JsonVariantRef::Null,
178 JsonVariant::Bool(x) => (*x).into(),
179 JsonVariant::Number(x) => match x {
180 JsonNumber::PosInt(i) => (*i).into(),
181 JsonNumber::NegInt(i) => (*i).into(),
182 JsonNumber::Float(f) => (f.0).into(),
183 },
184 JsonVariant::String(x) => x.as_str().into(),
185 JsonVariant::Array(array) => {
186 JsonVariantRef::Array(array.iter().map(|x| x.as_ref()).collect())
187 }
188 JsonVariant::Object(object) => JsonVariantRef::Object(
189 object
190 .iter()
191 .map(|(k, v)| (k.as_str(), v.as_ref()))
192 .collect(),
193 ),
194 JsonVariant::Variant(v) => JsonVariantRef::Variant(v),
195 }
196 }
197}
198
199impl From<()> for JsonVariant {
200 fn from(_: ()) -> Self {
201 Self::Null
202 }
203}
204
205impl From<bool> for JsonVariant {
206 fn from(v: bool) -> Self {
207 Self::Bool(v)
208 }
209}
210
211impl<T: Into<JsonNumber>> From<T> for JsonVariant {
212 fn from(v: T) -> Self {
213 Self::Number(v.into())
214 }
215}
216
217impl From<&str> for JsonVariant {
218 fn from(v: &str) -> Self {
219 Self::String(v.to_string())
220 }
221}
222
223impl From<String> for JsonVariant {
224 fn from(v: String) -> Self {
225 Self::String(v)
226 }
227}
228
229impl<const N: usize, T: Into<JsonVariant>> From<[T; N]> for JsonVariant {
230 fn from(vs: [T; N]) -> Self {
231 Self::Array(vs.into_iter().map(|x| x.into()).collect())
232 }
233}
234
235impl<K: Into<String>, V: Into<JsonVariant>, const N: usize> From<[(K, V); N]> for JsonVariant {
236 fn from(vs: [(K, V); N]) -> Self {
237 Self::Object(vs.into_iter().map(|(k, v)| (k.into(), v.into())).collect())
238 }
239}
240
241impl From<serde_json::Value> for JsonVariant {
242 fn from(v: serde_json::Value) -> Self {
243 fn helper(v: serde_json::Value) -> JsonVariant {
244 match v {
245 serde_json::Value::Null => JsonVariant::Null,
246 serde_json::Value::Bool(b) => b.into(),
247 serde_json::Value::Number(n) => n.into(),
248 serde_json::Value::String(s) => s.into(),
249 serde_json::Value::Array(array) => {
250 JsonVariant::Array(array.into_iter().map(helper).collect())
251 }
252 serde_json::Value::Object(object) => {
253 JsonVariant::Object(object.into_iter().map(|(k, v)| (k, helper(v))).collect())
254 }
255 }
256 }
257 helper(v)
258 }
259}
260
261impl From<BTreeMap<String, JsonVariant>> for JsonVariant {
262 fn from(v: BTreeMap<String, JsonVariant>) -> Self {
263 Self::Object(v)
264 }
265}
266
267impl Display for JsonVariant {
268 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
269 match self {
270 Self::Null => write!(f, "null"),
271 Self::Bool(x) => write!(f, "{x}"),
272 Self::Number(x) => write!(f, "{x}"),
273 Self::String(x) => write!(f, "{x}"),
274 Self::Array(array) => write!(
275 f,
276 "[{}]",
277 array
278 .iter()
279 .map(|x| x.to_string())
280 .collect::<Vec<_>>()
281 .join(", ")
282 ),
283 Self::Object(object) => {
284 write!(
285 f,
286 "{{ {} }}",
287 object
288 .iter()
289 .map(|(k, v)| format!("{k}: {v}"))
290 .collect::<Vec<_>>()
291 .join(", ")
292 )
293 }
294 Self::Variant(x) => match decode_json_variant(x) {
295 Ok(v) => write!(f, "{v}"),
296 Err(_) => write!(f, "{x:?}"),
297 },
298 }
299 }
300}
301
302#[derive(Debug, Eq, Serialize, Deserialize)]
304pub struct JsonValue {
305 #[serde(skip)]
306 json_type: OnceLock<Arc<JsonNativeType>>,
307 json_variant: JsonVariant,
308}
309
310impl JsonValue {
311 pub fn null() -> Self {
312 ().into()
313 }
314
315 pub(crate) fn new(json_variant: JsonVariant) -> Self {
316 Self {
317 json_type: OnceLock::new(),
318 json_variant,
319 }
320 }
321
322 pub(crate) fn data_type(&self) -> ConcreteDataType {
323 ConcreteDataType::json2(self.json_type().clone())
324 }
325
326 pub(crate) fn json_type(&self) -> &JsonNativeType {
327 self.json_type
328 .get_or_init(|| Arc::new(self.json_variant.native_type()))
329 .as_ref()
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: &JsonNativeType) -> Result<()> {
434 if is_include(expected, self.json_type()) && !self.json_variant.contains_empty_object() {
435 return Ok(());
436 }
437
438 fn helper(value: JsonVariant, expected: &JsonNativeType) -> Result<JsonVariant> {
439 Ok(match (value, expected) {
440 (JsonVariant::Null, _) | (_, JsonNativeType::Null) => JsonVariant::Null,
441 (JsonVariant::Bool(v), JsonNativeType::Bool) => JsonVariant::Bool(v),
442 (JsonVariant::Number(v), JsonNativeType::Number(n)) => {
443 return match n {
444 JsonNumberType::U64 => v
445 .as_u64()
446 .map(|x| JsonVariant::Number(JsonNumber::PosInt(x))),
447 JsonNumberType::I64 => v
448 .as_i64()
449 .map(|x| JsonVariant::Number(JsonNumber::NegInt(x))),
450 JsonNumberType::F64 => {
451 Some(JsonVariant::Number(JsonNumber::Float(v.as_f64().into())))
452 }
453 }
454 .with_context(|| AlignJsonValueSnafu {
455 reason: format!("unable to align number ‘{}’ to type {}", v, expected),
456 });
457 }
458 (JsonVariant::String(v), JsonNativeType::String) => JsonVariant::String(v),
459
460 (JsonVariant::Array(items), JsonNativeType::Array(expected)) => JsonVariant::Array(
461 items
462 .into_iter()
463 .map(|item| helper(item, expected.as_ref()))
464 .collect::<Result<_>>()?,
465 ),
466
467 (JsonVariant::Object(mut kvs), JsonNativeType::Object(expected)) => {
468 ensure!(
469 expected.keys().len() >= kvs.keys().len()
470 && kvs.keys().all(|k| expected.contains_key(k)),
471 AlignJsonValueSnafu {
472 reason: format!(
473 "aligned type '{}' should be superset of value '{}'",
474 JsonNativeType::Object(expected.clone()),
475 JsonVariant::from(kvs),
476 )
477 }
478 );
479
480 for (field, field_type) in expected {
481 if let Some((k, v)) = kvs.remove_entry(field) {
482 kvs.insert(k, helper(v, field_type)?);
483 }
484 }
485 JsonVariant::Object(kvs)
486 }
487
488 (v, JsonNativeType::Variant) => JsonVariant::Variant(encode_json_variant(v)?),
489
490 (value, expected) => {
491 return AlignJsonValueSnafu {
492 reason: format!(
493 "unable to align '{}' of type {} to type {}",
494 value,
495 value.native_type(),
496 expected,
497 ),
498 }
499 .fail();
500 }
501 })
502 }
503
504 let x = std::mem::take(&mut self.json_variant);
505
506 self.json_variant = helper(x, expected)?;
507 self.json_type = OnceLock::new();
508 Ok(())
509 }
510}
511
512impl<T: Into<JsonVariant>> From<T> for JsonValue {
513 fn from(v: T) -> Self {
514 Self {
515 json_type: OnceLock::new(),
516 json_variant: v.into(),
517 }
518 }
519}
520
521impl TryFrom<JsonValue> for serde_json::Value {
522 type Error = serde_json::Error;
523
524 fn try_from(v: JsonValue) -> serde_json::Result<Self> {
525 fn helper(v: JsonVariant) -> serde_json::Result<serde_json::Value> {
526 Ok(match v {
527 JsonVariant::Null => serde_json::Value::Null,
528 JsonVariant::Bool(x) => serde_json::Value::Bool(x),
529 JsonVariant::Number(x) => match x {
530 JsonNumber::PosInt(i) => serde_json::Value::Number(i.into()),
531 JsonNumber::NegInt(i) => serde_json::Value::Number(i.into()),
532 JsonNumber::Float(f) => {
533 if let Some(x) = Number::from_f64(f.0) {
534 serde_json::Value::Number(x)
535 } else {
536 serde_json::Value::String("NaN".into())
537 }
538 }
539 },
540 JsonVariant::String(x) => serde_json::Value::String(x),
541 JsonVariant::Array(array) => serde_json::Value::Array(
542 array
543 .into_iter()
544 .map(helper)
545 .collect::<serde_json::Result<Vec<_>>>()?,
546 ),
547 JsonVariant::Object(object) => {
548 let mut map = serde_json::Map::with_capacity(object.len());
549 for (k, v) in object {
550 map.insert(k, helper(v)?);
551 }
552 serde_json::Value::Object(map)
553 }
554 JsonVariant::Variant(x) => decode_json_variant(&x).map_err(|err| {
555 serde_json::Error::io(std::io::Error::new(
556 std::io::ErrorKind::InvalidData,
557 err.to_string(),
558 ))
559 })?,
560 })
561 }
562 helper(v.json_variant)
563 }
564}
565
566pub(crate) fn encode_json_variant(value: JsonVariant) -> Result<Vec<u8>> {
567 match value {
568 JsonVariant::Variant(bytes) => Ok(bytes),
569 value => jsonb::Value::try_from(value).map(|value| value.to_vec()),
570 }
571}
572
573pub(crate) fn decode_json_variant(
574 bytes: &[u8],
575) -> std::result::Result<serde_json::Value, jsonb::Error> {
576 jsonb::from_slice(bytes).map(Into::into)
577}
578
579pub(crate) fn encode_serde_json_as_jsonb(value: serde_json::Value) -> Vec<u8> {
580 jsonb::Value::from(value).to_vec()
581}
582
583impl TryFrom<JsonVariant> for jsonb::Value<'static> {
584 type Error = crate::Error;
585
586 fn try_from(value: JsonVariant) -> Result<Self> {
587 Ok(match value {
588 JsonVariant::Null => jsonb::Value::Null,
589 JsonVariant::Bool(value) => jsonb::Value::Bool(value),
590 JsonVariant::Number(value) => jsonb::Value::Number(value.try_into()?),
591 JsonVariant::String(value) => jsonb::Value::String(value.into()),
592 JsonVariant::Array(values) => jsonb::Value::Array(
593 values
594 .into_iter()
595 .map(jsonb::Value::try_from)
596 .collect::<Result<_>>()?,
597 ),
598 JsonVariant::Object(values) => jsonb::Value::Object(
599 values
600 .into_iter()
601 .map(|(key, value)| jsonb::Value::try_from(value).map(|value| (key, value)))
602 .collect::<Result<_>>()?,
603 ),
604 JsonVariant::Variant(value) => {
605 let value = decode_json_variant(&value)
606 .map_err(|error| InvalidJsonbSnafu { error }.build())?;
607 jsonb::Value::from(value)
608 }
609 })
610 }
611}
612
613impl TryFrom<JsonNumber> for jsonb::Number {
614 type Error = crate::Error;
615
616 fn try_from(value: JsonNumber) -> Result<Self> {
617 Ok(match value {
618 JsonNumber::PosInt(value) => jsonb::Number::UInt64(value),
619 JsonNumber::NegInt(value) => jsonb::Number::Int64(value),
620 JsonNumber::Float(value) => {
621 ensure!(
622 !value.0.is_nan(),
623 InvalidJsonSnafu {
624 value: "NaN is not a valid JSON number"
625 }
626 );
627 jsonb::Number::Float64(value.0)
628 }
629 })
630 }
631}
632
633impl Clone for JsonValue {
634 fn clone(&self) -> Self {
635 let Self {
636 json_type: _,
637 json_variant,
638 } = self;
639 Self {
640 json_type: OnceLock::new(),
641 json_variant: json_variant.clone(),
642 }
643 }
644}
645
646impl PartialEq<JsonValue> for JsonValue {
647 fn eq(&self, other: &JsonValue) -> bool {
648 let Self {
649 json_type: _,
650 json_variant,
651 } = self;
652 json_variant.eq(&other.json_variant)
653 }
654}
655
656impl Hash for JsonValue {
657 fn hash<H: Hasher>(&self, state: &mut H) {
658 let Self {
659 json_type: _,
660 json_variant,
661 } = self;
662 json_variant.hash(state);
663 }
664}
665
666impl Display for JsonValue {
667 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
668 write!(f, "{}", self.json_variant)
669 }
670}
671
672#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
674pub enum JsonVariantRef<'a> {
675 Null,
676 Bool(bool),
677 Number(JsonNumber),
678 String(&'a str),
679 Array(Vec<JsonVariantRef<'a>>),
680 Object(BTreeMap<&'a str, JsonVariantRef<'a>>),
681 Variant(&'a [u8]),
682}
683
684impl JsonVariantRef<'_> {
685 fn native_type(&self) -> JsonNativeType {
686 match self {
687 JsonVariantRef::Null => JsonNativeType::Null,
688 JsonVariantRef::Bool(_) => JsonNativeType::Bool,
689 JsonVariantRef::Number(n) => n.native_type(),
690 JsonVariantRef::String(_) => JsonNativeType::String,
691 JsonVariantRef::Array(array) => {
692 json_array_native_type(array.iter().map(JsonVariantRef::native_type))
693 }
694 JsonVariantRef::Object(object) => {
695 json_object_native_type(object.iter().map(|(k, v)| (*k, v.native_type())))
696 }
697 JsonVariantRef::Variant(_) => JsonNativeType::Variant,
698 }
699 }
700}
701
702fn json_array_native_type<I>(items: I) -> JsonNativeType
703where
704 I: IntoIterator<Item = JsonNativeType>,
705{
706 let mut iter = items.into_iter();
707 let mut item_type = match iter.next() {
708 Some(t) => t,
709 None => return JsonNativeType::Array(Box::new(JsonNativeType::Null)),
710 };
711
712 for x in iter {
713 if matches!(item_type, JsonNativeType::Variant) {
714 break;
715 }
716 item_type.merge(&x);
717 }
718 JsonNativeType::Array(Box::new(item_type))
719}
720
721fn json_object_native_type<I, K>(fields: I) -> JsonNativeType
722where
723 I: IntoIterator<Item = (K, JsonNativeType)>,
724 K: Into<String>,
725{
726 let mut fields = fields.into_iter().peekable();
727 if fields.peek().is_none() {
728 JsonNativeType::Null
729 } else {
730 JsonNativeType::Object(fields.map(|(k, v)| (k.into(), v)).collect())
731 }
732}
733
734impl From<()> for JsonVariantRef<'_> {
735 fn from(_: ()) -> Self {
736 Self::Null
737 }
738}
739
740impl From<bool> for JsonVariantRef<'_> {
741 fn from(v: bool) -> Self {
742 Self::Bool(v)
743 }
744}
745
746impl<T: Into<JsonNumber>> From<T> for JsonVariantRef<'_> {
747 fn from(v: T) -> Self {
748 Self::Number(v.into())
749 }
750}
751
752impl<'a> From<&'a str> for JsonVariantRef<'a> {
753 fn from(v: &'a str) -> Self {
754 Self::String(v)
755 }
756}
757
758impl<'a, const N: usize, T: Into<JsonVariantRef<'a>>> From<[T; N]> for JsonVariantRef<'a> {
759 fn from(vs: [T; N]) -> Self {
760 Self::Array(vs.into_iter().map(|x| x.into()).collect())
761 }
762}
763
764impl<'a, V: Into<JsonVariantRef<'a>>, const N: usize> From<[(&'a str, V); N]>
765 for JsonVariantRef<'a>
766{
767 fn from(vs: [(&'a str, V); N]) -> Self {
768 Self::Object(vs.into_iter().map(|(k, v)| (k, v.into())).collect())
769 }
770}
771
772impl<'a> From<Vec<JsonVariantRef<'a>>> for JsonVariantRef<'a> {
773 fn from(v: Vec<JsonVariantRef<'a>>) -> Self {
774 Self::Array(v)
775 }
776}
777
778impl<'a> From<BTreeMap<&'a str, JsonVariantRef<'a>>> for JsonVariantRef<'a> {
779 fn from(v: BTreeMap<&'a str, JsonVariantRef<'a>>) -> Self {
780 Self::Object(v)
781 }
782}
783
784impl From<&JsonVariantRef<'_>> for JsonVariant {
785 fn from(v: &JsonVariantRef) -> Self {
786 match v {
787 JsonVariantRef::Null => Self::Null,
788 JsonVariantRef::Bool(x) => Self::Bool(*x),
789 JsonVariantRef::Number(x) => Self::Number(*x),
790 JsonVariantRef::String(x) => Self::String(x.to_string()),
791 JsonVariantRef::Array(array) => Self::Array(array.iter().map(Into::into).collect()),
792 JsonVariantRef::Object(object) => Self::Object(
793 object
794 .iter()
795 .map(|(k, v)| (k.to_string(), v.into()))
796 .collect(),
797 ),
798 JsonVariantRef::Variant(x) => Self::Variant(x.to_vec()),
799 }
800 }
801}
802
803impl<'a> From<&'a [u8]> for JsonVariantRef<'a> {
804 fn from(value: &'a [u8]) -> Self {
805 Self::Variant(value)
806 }
807}
808
809#[derive(Debug, Serialize)]
811pub struct JsonValueRef<'a> {
812 #[serde(skip)]
813 json_type: OnceLock<Arc<JsonNativeType>>,
814 json_variant: JsonVariantRef<'a>,
815}
816
817impl<'a> JsonValueRef<'a> {
818 pub fn null() -> Self {
819 ().into()
820 }
821
822 pub fn new_with_type(json_variant: JsonVariantRef<'a>, json_type: JsonNativeType) -> Self {
825 Self {
826 json_type: OnceLock::from(Arc::new(json_type)),
827 json_variant,
828 }
829 }
830
831 pub(crate) fn data_type(&self) -> ConcreteDataType {
832 ConcreteDataType::json2(self.json_type().as_ref().clone())
833 }
834
835 pub(crate) fn json_type(&self) -> Arc<JsonNativeType> {
836 self.json_type
837 .get_or_init(|| Arc::new(self.json_variant.native_type()))
838 .clone()
839 }
840
841 pub fn into_variant(self) -> JsonVariantRef<'a> {
842 self.json_variant
843 }
844
845 pub(crate) fn is_null(&self) -> bool {
846 matches!(self.json_variant, JsonVariantRef::Null)
847 }
848
849 pub fn is_object(&self) -> bool {
850 matches!(self.json_variant, JsonVariantRef::Object(_))
851 }
852
853 pub(crate) fn as_f32(&self) -> Option<f32> {
854 match self.json_variant {
855 JsonVariantRef::Number(JsonNumber::Float(f)) => f.to_f32(),
856 _ => None,
857 }
858 }
859
860 pub(crate) fn as_f64(&self) -> Option<f64> {
861 match self.json_variant {
862 JsonVariantRef::Number(JsonNumber::Float(f)) => Some(f.0),
863 _ => None,
864 }
865 }
866
867 pub(crate) fn data_size(&self) -> usize {
868 size_of_val(self)
869 }
870
871 pub(crate) fn variant(&self) -> &JsonVariantRef<'a> {
872 &self.json_variant
873 }
874}
875
876impl<'a, T: Into<JsonVariantRef<'a>>> From<T> for JsonValueRef<'a> {
877 fn from(v: T) -> Self {
878 Self {
879 json_type: OnceLock::new(),
880 json_variant: v.into(),
881 }
882 }
883}
884
885impl From<JsonValueRef<'_>> for JsonValue {
886 fn from(v: JsonValueRef<'_>) -> Self {
887 Self {
888 json_type: OnceLock::new(),
889 json_variant: JsonVariant::from(&v.json_variant),
890 }
891 }
892}
893
894impl PartialEq for JsonValueRef<'_> {
895 fn eq(&self, other: &Self) -> bool {
896 let Self {
897 json_type: _,
898 json_variant,
899 } = self;
900 json_variant == &other.json_variant
901 }
902}
903
904impl Eq for JsonValueRef<'_> {}
905
906impl Clone for JsonValueRef<'_> {
907 fn clone(&self) -> Self {
908 let Self {
909 json_type: _,
910 json_variant,
911 } = self;
912 Self {
913 json_type: OnceLock::new(),
914 json_variant: json_variant.clone(),
915 }
916 }
917}
918
919#[cfg(test)]
920mod tests {
921 use super::*;
922 use crate::types::json_type::JsonObjectType;
923
924 fn jsonb_bytes(json: &str) -> Vec<u8> {
925 let value: serde_json::Value = serde_json::from_str(json).unwrap();
926 encode_json_variant(value.into()).unwrap()
927 }
928
929 #[test]
930 fn test_align_json_value() -> Result<()> {
931 fn parse_json_value(json: &str) -> JsonValue {
932 let value: serde_json::Value = serde_json::from_str(json).unwrap();
933 value.into()
934 }
935
936 let mut value = JsonValue::from(true);
938 assert_eq!(value.json_type(), &JsonNativeType::Bool);
939 value.try_align(&JsonNativeType::Null)?;
940 assert_eq!(value, JsonValue::null());
941 assert_eq!(value.json_type(), &JsonNativeType::Null);
942
943 let expected = JsonNativeType::Object(JsonObjectType::from([
946 ("extra".to_string(), JsonNativeType::u64()),
947 (
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 ("note".to_string(), JsonNativeType::String),
953 ])))),
954 ),
955 ("name".to_string(), JsonNativeType::String),
956 ]));
957 let mut value = parse_json_value(r#"{"items":[{"id":1,"payload":{"k":"v"}}],"extra":1}"#);
958 assert_ne!(value.json_type(), &expected);
959 value.try_align(&expected)?;
960 assert_eq!(
961 value,
962 JsonValue::from(JsonVariant::Object(BTreeMap::from([
963 ("extra".to_string(), JsonVariant::from(1_u64)),
964 (
965 "items".to_string(),
966 JsonVariant::Array(vec![JsonVariant::Object(BTreeMap::from([
967 ("id".to_string(), JsonVariant::from(1_u64)),
968 (
969 "payload".to_string(),
970 JsonVariant::Variant(jsonb_bytes(r#"{"k":"v"}"#)),
971 ),
972 ]))]),
973 ),
974 ])))
975 );
976
977 let expected = JsonNativeType::Object(JsonObjectType::from([(
980 "empty".to_string(),
981 JsonNativeType::Null,
982 )]));
983 let mut value = parse_json_value(r#"{"empty":{}}"#);
984 assert_eq!(value.json_type(), &expected);
985 value.try_align(&expected)?;
986 assert_eq!(
987 value,
988 JsonValue::from(JsonVariant::Object(BTreeMap::from([(
989 "empty".to_string(),
990 JsonVariant::Null,
991 )])))
992 );
993
994 let expected = JsonNativeType::Object(JsonObjectType::from([(
996 "items".to_string(),
997 JsonNativeType::Array(Box::new(JsonNativeType::Object(JsonObjectType::from([
998 ("id".to_string(), JsonNativeType::u64()),
999 ("payload".to_string(), JsonNativeType::Variant),
1000 ])))),
1001 )]));
1002 let mut value =
1003 parse_json_value(r#"{"items":[{"id":1,"payload":{"k":"v"},"extra":true}]}"#);
1004 let err = value.try_align(&expected).unwrap_err();
1005 assert_eq!(
1006 err.to_string(),
1007 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 } }'"#
1008 );
1009
1010 let mut value = parse_json_value(r#"{"foo":[1,true,null]}"#);
1012 value.try_align(&JsonNativeType::Variant)?;
1013 assert_eq!(
1014 value,
1015 JsonValue::from(JsonVariant::Variant(jsonb_bytes(
1016 r#"{"foo":[1,true,null]}"#
1017 )))
1018 );
1019
1020 let mut value = JsonValue::from("hello");
1022 let err = value.try_align(&JsonNativeType::Bool).unwrap_err();
1023 assert_eq!(
1024 err.to_string(),
1025 r#"Failed to align JSON value, reason: unable to align 'hello' of type "<String>" to type "<Bool>""#
1026 );
1027
1028 let mut value = JsonValue::from(f64::NAN);
1029 let err = value.try_align(&JsonNativeType::Variant).unwrap_err();
1030 assert_eq!(
1031 err.to_string(),
1032 "Invalid JSON: NaN is not a valid JSON number"
1033 );
1034
1035 Ok(())
1036 }
1037}