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