use std::fmt::Write as _;
use crate::QueryValue;
pub(super) fn escape_csv_field(value: &str) -> String {
if value.contains([',', '"', '\n', '\r']) {
format!("\"{}\"", value.replace('"', "\"\""))
} else {
value.to_owned()
}
}
pub(super) fn escape_json_string(value: &str) -> String {
let mut escaped = String::from("\"");
for character in value.chars() {
match character {
'"' => escaped.push_str("\\\""),
'\\' => escaped.push_str("\\\\"),
'\n' => escaped.push_str("\\n"),
'\r' => escaped.push_str("\\r"),
'\t' => escaped.push_str("\\t"),
'\u{08}' => escaped.push_str("\\b"),
'\u{0C}' => escaped.push_str("\\f"),
c if c <= '\u{1F}' => {
let _ = write!(&mut escaped, "\\u{:04x}", c as u32);
}
c => escaped.push(c),
}
}
escaped.push('"');
escaped
}
pub(super) fn to_json_value(value: &QueryValue) -> String {
match value {
QueryValue::Null => "null".to_owned(),
QueryValue::Integer(number) => number.to_string(),
QueryValue::Real(number) if number.is_finite() => number.to_string(),
QueryValue::Real(_) => "null".to_owned(),
QueryValue::Text(text) => escape_json_string(text),
}
}
pub(super) fn escape_markdown_cell(value: &str) -> String {
value.replace('|', "\\|").replace('\n', "<br>")
}
pub(super) fn escape_xml_text(value: &str) -> String {
value
.replace('&', "&")
.replace('<', "<")
.replace('>', ">")
.replace('"', """)
.replace('\'', "'")
}
pub(super) fn escape_xml_tag(value: &str) -> String {
let sanitized = value
.chars()
.map(|character| {
if character.is_alphanumeric() || character == '_' || character == '-' {
character
} else {
'_'
}
})
.collect::<String>();
if sanitized.is_empty() {
"element".to_owned()
} else if sanitized.chars().next().unwrap_or('x').is_numeric() {
format!("_{sanitized}")
} else {
sanitized
}
}