kutil_std/string/
escape.rs1pub const ESCAPE_CHARACTER: char = '\\';
3
4pub trait Escape {
10 fn unescape(&self, pattern: &str) -> String;
12
13 fn find_ignore_escaped(&self, pattern: &str) -> Option<usize>;
15
16 fn split_once_ignore_escaped(&self, pattern: &str) -> Option<(&str, &str)>;
18}
19
20impl Escape for str {
21 fn unescape(&self, pattern: &str) -> String {
22 let escaped_pattern = String::from(ESCAPE_CHARACTER) + pattern;
23 self.replace(&escaped_pattern, pattern)
24 }
25
26 fn find_ignore_escaped(&self, pattern: &str) -> Option<usize> {
27 let pattern_chars: Vec<_> = pattern.chars().collect();
28 let pattern_chars_count = pattern_chars.len();
29
30 let mut escaped = false;
31 let mut pattern_chars_index = 0;
32
33 for (byte_index, c) in self.char_indices() {
34 if c == pattern_chars[pattern_chars_index] {
35 pattern_chars_index += 1;
36 if pattern_chars_index == pattern_chars_count {
37 if escaped {
38 pattern_chars_index = 0;
39 escaped = false;
40 } else {
41 return Some(byte_index - pattern.len() + 1);
42 }
43 }
44 } else if c == ESCAPE_CHARACTER {
45 escaped = true;
46 } else {
47 escaped = false;
48 }
49 }
50
51 None
52 }
53
54 fn split_once_ignore_escaped(&self, pattern: &str) -> Option<(&str, &str)> {
55 self.find_ignore_escaped(pattern).map(|index| (&self[..index], &self[index + pattern.len()..]))
56 }
57}