uqa_sql/expr/
json_carrier.rs1use uqa_core::Value;
10
11pub fn core_value_to_json(value: &Value) -> serde_json::Value {
12 match value {
13 Value::Null => serde_json::Value::Null,
14 Value::Void => serde_json::Value::String(String::new()),
15 Value::Bool(b) => serde_json::Value::Bool(*b),
16 Value::Int(i) => serde_json::Value::Number((*i).into()),
17 Value::Float(f) => serde_json::Number::from_f64(*f).map_or_else(
18 || {
19 let label = if f.is_nan() {
20 "NaN"
21 } else if f.is_sign_positive() {
22 "Infinity"
23 } else {
24 "-Infinity"
25 };
26 serde_json::Value::String(label.to_string())
27 },
28 serde_json::Value::Number,
29 ),
30 Value::Decimal(d) => d
31 .to_f64()
32 .and_then(serde_json::Number::from_f64)
33 .map_or_else(
34 || serde_json::Value::String(d.to_sql_string()),
35 serde_json::Value::Number,
36 ),
37 Value::Str(s) => serde_json::from_str::<serde_json::Value>(s)
38 .unwrap_or_else(|_| serde_json::Value::String(s.clone())),
39 Value::FixedChar(s) => serde_json::Value::String(s.trim_end_matches(' ').to_string()),
40 Value::Bytes(bytes) => serde_json::Value::String(String::from_utf8_lossy(bytes).into()),
41 Value::Temporal(t) => serde_json::Value::String(t.to_sql_string()),
42 Value::Json(text) | Value::JsonB(text) => {
43 serde_json::from_str(text).unwrap_or_else(|_| serde_json::Value::String(text.clone()))
44 }
45 Value::Array(array) => {
46 serde_json::Value::Array(array.elements().iter().map(core_value_to_json).collect())
47 }
48 Value::LegacyVector(vector) => {
49 serde_json::Value::Array(vector.elements().iter().map(core_value_to_json).collect())
50 }
51 Value::List(items) => {
52 serde_json::Value::Array(items.iter().map(core_value_to_json).collect())
53 }
54 Value::Row(values) => serde_json::Value::Object(
55 values
56 .iter()
57 .enumerate()
58 .map(|(index, value)| (format!("f{}", index + 1), core_value_to_json(value)))
59 .collect(),
60 ),
61 Value::Record(fields) => serde_json::Value::Object(
62 fields
63 .iter()
64 .map(|(name, value)| (name.clone(), core_value_to_json(value)))
65 .collect(),
66 ),
67 Value::Map(map) => serde_json::Value::Object(
68 map.iter()
69 .map(|(k, v)| (k.clone(), core_value_to_json(v)))
70 .collect(),
71 ),
72 }
73}
74
75pub fn value_to_text(value: &Value) -> String {
76 value_to_text_with_control(value, &uqa_core::memory::ProductionControl::uncontrolled())
77 .expect("ordinary carrier text production")
78 .into_uncontrolled()
79 .expect("ordinary carrier text")
80}
81
82pub fn value_to_text_with_control(
83 value: &Value,
84 control: &uqa_core::memory::ProductionControl<'_>,
85) -> crate::error::Result<uqa_core::memory::Produced<String>> {
86 control.check()?;
87 Ok(match value {
88 Value::Null | Value::Void => control.copy_text("")?,
89 Value::Bool(value) => control.format(format_args!("{value}"))?,
90 Value::Int(value) => control.format(format_args!("{value}"))?,
91 Value::Float(value) => control.format(format_args!("{value}"))?,
92 Value::Decimal(value) => value.to_sql_string_with_control(control)?,
93 Value::Str(value) | Value::Json(value) | Value::JsonB(value) => control.copy_text(value)?,
94 Value::FixedChar(value) => control.copy_text(value.trim_end_matches(' '))?,
95 Value::Bytes(value) => super::json::utf8_lossy_with_control(value, control)?,
96 Value::Temporal(value) => value.to_sql_string_with_control(control)?,
97 Value::Array(array) => {
98 super::conversion::array_value_to_string_with_control(array, control)?
99 }
100 Value::List(_) | Value::Map(_) => {
101 super::json::format_core_value_as_json_with_control(value, control)?
102 }
103 Value::Row(_) | Value::Record(_) | Value::LegacyVector(_) => {
104 super::conversion::value_to_string_with_control(value, control)?
105 }
106 })
107}