use crate::db::query::{self, Cell};
pub fn format_value(value: &Cell, type_name: &str) -> String {
let Some(text) = value else {
return "NULL".to_string();
};
if query::is_placeholder(value) {
return format!(
"{text}\n\nThis value was not read back from the server, so there is \
nothing to show here."
);
}
let upper = type_name.to_ascii_uppercase();
let json = !upper.ends_with("[]")
&& (upper.starts_with("JSON") || text.trim_start().starts_with(['{', '[']));
if json && let Some(pretty) = pretty_json(text) {
return pretty;
}
text.clone()
}
const LONG_VALUE: usize = 200;
pub fn needs_a_window(value: &Cell, type_name: &str) -> bool {
if query::is_placeholder(value) || query::is_binary_type(type_name) {
return true;
}
let Some(text) = value else {
return false;
};
let head: String = text.chars().take(LONG_VALUE + 1).collect();
if head.contains('\n') || head.chars().count() > LONG_VALUE {
return true;
}
(type_name.to_ascii_uppercase().starts_with("JSON")
|| text.trim_start().starts_with(['{', '[']))
&& pretty_json(text).is_some()
}
fn pretty_json(text: &str) -> Option<String> {
let value: serde_json::Value = serde_json::from_str(text).ok()?;
serde_json::to_string_pretty(&value).ok()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn json_is_laid_out_for_reading() {
let value = Some(r#"{"b":1,"a":[1,2]}"#.to_string());
assert_eq!(
format_value(&value, "JSONB"),
"{\n \"b\": 1,\n \"a\": [\n 1,\n 2\n ]\n}"
);
assert_eq!(format_value(&Some("\"hi\"".to_string()), "JSON"), "\"hi\"");
}
#[test]
fn everything_else_is_left_as_it_is() {
let text = "a long line of plain text".to_string();
assert_eq!(format_value(&Some(text.clone()), "TEXT"), text);
assert_eq!(format_value(&None, "TEXT"), "NULL");
let broken = "{not json".to_string();
assert_eq!(format_value(&Some(broken.clone()), "TEXT"), broken);
}
#[test]
fn a_value_that_was_never_read_says_so() {
let described = format_value(&query::blob(b"abc"), "BLOB");
assert!(described.starts_with("<3 bytes>"), "{described}");
assert!(described.contains("not read back"), "{described}");
}
}