use super::{arrays, scalars};
use serde_json::Value;
use sqlx::{Row, ValueRef};
pub(super) fn decode(row: &sqlx::postgres::PgRow, name: &str) -> Value {
if let Ok(value) = row.try_get::<String, _>(name) {
return Value::String(value);
}
if let Ok(value) = row.try_get::<bool, _>(name) {
return serde_json::json!(value);
}
if let Some(value) = scalars::integer(row, name) {
return value;
}
if let Some(value) = scalars::float(row, name) {
return value;
}
if let Ok(value) = row.try_get::<Value, _>(name) {
return value;
}
if let Some(value) = scalars::stringly(row, name) {
return value;
}
if let Some(value) = arrays::pg_array(row, name) {
return value;
}
if let Some(value) = arrays::pg_bytes(row, name) {
return value;
}
raw(row, name)
}
fn raw(row: &sqlx::postgres::PgRow, name: &str) -> Value {
let Ok(value) = row.try_get_raw(name) else {
return Value::String("<unprintable>".to_string());
};
let type_name = value.type_info().to_string();
let Ok(bytes) = value.as_bytes() else {
return Value::String(format!("<{type_name}>"));
};
match std::str::from_utf8(bytes) {
Ok(text) if text.chars().all(|c| !c.is_control()) => Value::String(text.to_string()),
_ => Value::String(format!("<{type_name}, {} bytes>", bytes.len())),
}
}