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