1use serde_json::Value as Json;
16use toasty_core::stmt::{self, Value};
17
18pub fn value_to_json(value: &Value) -> Json {
22 match value {
23 Value::Null => Json::Null,
24 Value::Bool(v) => Json::Bool(*v),
25 Value::I8(v) => Json::Number((*v).into()),
26 Value::I16(v) => Json::Number((*v).into()),
27 Value::I32(v) => Json::Number((*v).into()),
28 Value::I64(v) => Json::Number((*v).into()),
29 Value::U8(v) => Json::Number((*v).into()),
30 Value::U16(v) => Json::Number((*v).into()),
31 Value::U32(v) => Json::Number((*v).into()),
32 Value::U64(v) => Json::Number((*v).into()),
33 Value::F32(v) => serde_json::Number::from_f64((*v).into())
34 .map(Json::Number)
35 .unwrap_or(Json::Null),
36 Value::F64(v) => serde_json::Number::from_f64(*v)
37 .map(Json::Number)
38 .unwrap_or(Json::Null),
39 Value::String(v) => Json::String(v.clone()),
40 Value::Uuid(v) => Json::String(v.to_string()),
41 #[cfg(feature = "rust_decimal")]
42 Value::Decimal(v) => Json::String(v.to_string()),
43 #[cfg(feature = "bigdecimal")]
44 Value::BigDecimal(v) => Json::String(v.to_string()),
45 #[cfg(feature = "jiff")]
46 Value::Timestamp(v) => Json::String(v.to_string()),
47 #[cfg(feature = "jiff")]
48 Value::Zoned(v) => Json::String(v.to_string()),
49 #[cfg(feature = "jiff")]
50 Value::Date(v) => Json::String(v.to_string()),
51 #[cfg(feature = "jiff")]
52 Value::Time(v) => Json::String(v.to_string()),
53 #[cfg(feature = "jiff")]
54 Value::DateTime(v) => Json::String(v.to_string()),
55 _ => todo!("encode {value:?} as JSON"),
56 }
57}
58
59pub fn value_from_json(json: Json, ty: &stmt::Type) -> Value {
61 match (ty, json) {
62 (_, Json::Null) => Value::Null,
63 (stmt::Type::Bool, Json::Bool(v)) => Value::Bool(v),
64 (stmt::Type::String, Json::String(v)) => Value::String(v),
65 (stmt::Type::Uuid, Json::String(v)) => {
66 Value::Uuid(v.parse().expect("invalid UUID in JSON"))
67 }
68 (stmt::Type::I8, Json::Number(n)) => Value::I8(n.as_i64().unwrap() as i8),
69 (stmt::Type::I16, Json::Number(n)) => Value::I16(n.as_i64().unwrap() as i16),
70 (stmt::Type::I32, Json::Number(n)) => Value::I32(n.as_i64().unwrap() as i32),
71 (stmt::Type::I64, Json::Number(n)) => Value::I64(n.as_i64().unwrap()),
72 (stmt::Type::U8, Json::Number(n)) => Value::U8(n.as_u64().unwrap() as u8),
73 (stmt::Type::U16, Json::Number(n)) => Value::U16(n.as_u64().unwrap() as u16),
74 (stmt::Type::U32, Json::Number(n)) => Value::U32(n.as_u64().unwrap() as u32),
75 (stmt::Type::U64, Json::Number(n)) => Value::U64(n.as_u64().unwrap()),
76 (stmt::Type::F32, Json::Number(n)) => Value::F32(n.as_f64().unwrap() as f32),
77 (stmt::Type::F64, Json::Number(n)) => Value::F64(n.as_f64().unwrap()),
78 #[cfg(feature = "rust_decimal")]
79 (stmt::Type::Decimal, Json::String(v)) => {
80 Value::Decimal(v.parse().expect("invalid Decimal in JSON"))
81 }
82 #[cfg(feature = "bigdecimal")]
83 (stmt::Type::BigDecimal, Json::String(v)) => {
84 Value::BigDecimal(v.parse().expect("invalid BigDecimal in JSON"))
85 }
86 #[cfg(feature = "jiff")]
87 (stmt::Type::Timestamp, Json::String(v)) => {
88 Value::Timestamp(v.parse().expect("invalid Timestamp in JSON"))
89 }
90 #[cfg(feature = "jiff")]
91 (stmt::Type::Zoned, Json::String(v)) => {
92 Value::Zoned(v.parse().expect("invalid Zoned in JSON"))
93 }
94 #[cfg(feature = "jiff")]
95 (stmt::Type::Date, Json::String(v)) => {
96 Value::Date(v.parse().expect("invalid Date in JSON"))
97 }
98 #[cfg(feature = "jiff")]
99 (stmt::Type::Time, Json::String(v)) => {
100 Value::Time(v.parse().expect("invalid Time in JSON"))
101 }
102 #[cfg(feature = "jiff")]
103 (stmt::Type::DateTime, Json::String(v)) => {
104 Value::DateTime(v.parse().expect("invalid DateTime in JSON"))
105 }
106 (ty, json) => todo!("decode JSON value {json:?} as {ty:?}"),
107 }
108}
109
110pub fn value_list_to_json(value: &Value) -> Json {
113 let Value::List(items) = value else {
114 unreachable!("value_list_to_json called on {value:?}")
115 };
116 Json::Array(items.iter().map(value_to_json).collect())
117}
118
119pub fn value_list_from_json(json: Json, elem_ty: &stmt::Type) -> Value {
122 let Json::Array(items) = json else {
123 panic!("expected JSON array for Vec<scalar> column, got {json:?}")
124 };
125 Value::List(
126 items
127 .into_iter()
128 .map(|v| value_from_json(v, elem_ty))
129 .collect(),
130 )
131}