use std::str::Chars;
pub trait SimpleEnclose {
fn enclose_in_chars(& self, start: char, end: char, prefix: Option<&str>, escape_char: Option<char>) -> String;
fn enclose_escaped(& self, start: char, end: char, escape_char: Option<char>) -> String {
self.enclose_in_chars(start, end, None, escape_char)
}
fn enclose(& self, start: char, end: char) -> String {
self.enclose_in_chars(start, end, None, None)
}
fn enclose_safe(& self, start: char, end: char) -> String {
self.enclose_in_chars(start, end, None, Some('\\'))
}
fn wrap_escaped(& self, opening: char, escape_char: Option<char>) -> String {
let end = match opening {
'(' => ')',
'<' => '>',
'{' => '}',
'[' => ']',
_ => opening
};
self.enclose_in_chars(opening, end, None, escape_char)
}
fn wrap(& self, opening: char) -> String {
let end = match opening {
'(' => ')',
'<' => '>',
'{' => '}',
'[' => ']',
_ => opening
};
self.enclose_in_chars(opening, end, None, None)
}
fn wrap_safe(& self, opening: char) -> String {
let end = match opening {
'(' => ')',
'<' => '>',
'{' => '}',
'[' => ']',
_ => opening
};
self.enclose_in_chars(opening, end, None, Some('\\'))
}
fn in_parentheses(& self, prefix: Option<&str>) -> String {
self.enclose_in_chars('(', ')', prefix, None)
}
fn parenthesize(& self) -> String {
self.wrap('(')
}
fn parenthesize_safe(& self) -> String {
self.wrap_safe('(')
}
fn double_quotes(& self) -> String {
self.wrap('"')
}
fn single_quotes(& self) -> String {
self.wrap('\'')
}
fn double_quotes_safe(& self) -> String {
self.wrap_escaped('"', Some('\\'))
}
fn single_quotes_safe(& self) -> String {
self.wrap_escaped('\'', Some('\\'))
}
}
impl SimpleEnclose for str {
fn enclose_in_chars(&self, start: char, end: char, prefix: Option<&str>, escape_char: Option<char>) -> String {
let mut out = match escape_char {
Some(esc_char) => {
if self.contains(end) {
escape_in_str(self.chars(), end, esc_char)
} else {
self.to_owned()
}
},
_ => self.to_owned()
};
out.insert(0, start);
if let Some(pre) = prefix {
out.insert_str(1, pre);
}
out.push(end);
out
}
}
pub fn escape_in_str(chars: Chars, end: char, esc_char: char) -> String {
let mut new_string = String::new();
let mut prev_char = ' ';
for ch in chars {
if ch == end {
if prev_char != esc_char && new_string.len() > 0 {
new_string.push(esc_char);
}
}
new_string.push(ch);
prev_char = ch;
}
new_string
}