pub fn escape(string: String) -> String {
let escape_chars = vec!['"', '\''];
let mut inside_quotes = ' ';
let mut end = String::new();
let mut index: usize = 0;
let mut last_quote_index: usize = 0;
for c in string.chars() {
if escape_chars.contains(&c) && inside_quotes != c {
inside_quotes = c;
} else if escape_chars.contains(&c) && inside_quotes == c {
end.push('\\');
last_quote_index = index;
index += 1;
}
end.push(c);
index += 1;
}
if last_quote_index != 0 {
end.remove(last_quote_index);
}
end
}
#[cfg(test)]
mod tests {
use escape::escape;
#[test]
fn escape_single_quotes() {
let command = "'$x['a b']'";
let result = "'$x[\\'a b\\']'";
assert_eq!(escape(command.to_string()), result);
}
#[test]
fn escape_single_quotes_unchanged() {
let command = "'$x[\"a b\"]'";
let result = "'$x[\"a b\"]'";
assert_eq!(escape(command.to_string()), result);
}
#[test]
fn escape_quotes() {
let command = "\"$x[\"a b\"]\"";
let result = "\"$x[\\\"a b\\\"]\"";
assert_eq!(escape(command.to_string()), result);
}
#[test]
fn escape_inner_single_quotes() {
let command = "\"$x['a b']\"";
let result = "\"$x['a b']\"";
assert_eq!(escape(command.to_string()), result);
}
#[test]
fn escape_nothing() {
let string = "$x['a b']#$:";
assert_eq!(escape(string.to_string()), string);
}
}