#[cfg(test)]
mod test;
pub fn escape_literal(input: &str) -> String {
escape_internal(input, false)
}
pub fn escape_identifier(input: &str) -> String {
escape_internal(input, true)
}
fn escape_internal(input: &str, as_ident: bool) -> String {
let mut num_backslashes = 0;
let mut num_quotes = 0;
let quote_char = if as_ident { '"' } else { '\'' };
for ch in input.chars() {
if ch == quote_char {
num_quotes += 1;
} else if ch == '\\' {
num_backslashes += 1;
}
}
let mut result_size = input.len() + num_quotes + 3; if !as_ident && num_backslashes > 0 {
result_size += num_backslashes + 2;
}
let mut output = String::with_capacity(result_size);
if !as_ident && num_backslashes > 0 {
output.push(' ');
output.push('E');
}
output.push(quote_char);
if num_quotes == 0 && (num_backslashes == 0 || as_ident) {
output.push_str(input);
} else {
for ch in input.chars() {
if ch == quote_char || (!as_ident && ch == '\\') {
output.push(ch);
}
output.push(ch);
}
}
output.push(quote_char);
output
}