use fancy_regex::Regex;
use std::sync::LazyLock;
static NEEDS_QUOTING_REGEX: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r#"[\[\]:`\{\}#'";\(\)\|\$,\.\d\s!?=]|(?i)^[+\-]?(inf(inity)?|nan)$"#)
.expect("internal error: NEEDS_QUOTING_REGEX didn't compile")
});
pub fn needs_quoting(string: &str) -> bool {
if string.is_empty() {
return true;
}
match string {
"true" | "false" | "null" | "&&" => return true,
_ => (),
};
NEEDS_QUOTING_REGEX.is_match(string).unwrap_or(false)
}
pub fn escape_quote_string(string: &str) -> String {
let mut output = String::with_capacity(string.len() + 2);
output.push('"');
for c in string.chars() {
if c == '"' || c == '\\' {
output.push('\\');
}
output.push(c);
}
output.push('"');
output
}
pub fn as_raw_string(s: &str) -> Option<String> {
if !s.contains('"') && !s.contains('\\') {
return None;
}
let mut hash_count = 1;
loop {
let closing = format!("'{}", "#".repeat(hash_count));
if !s.contains(&closing) {
break;
}
hash_count += 1;
}
let hashes = "#".repeat(hash_count);
Some(format!("r{hashes}'{s}'{hashes}"))
}