1pub struct EscapeSequenceCleaner {
3 partial_line: String
4}
5
6impl Default for EscapeSequenceCleaner {
7 fn default() -> Self { Self::new() }
8}
9
10impl EscapeSequenceCleaner {
11 pub fn new() -> Self {
12 Self {
13 partial_line: String::new()
14 }
15 }
16
17 pub fn process_line(&mut self, mut line: String) -> Option<String> {
19 if line.starts_with("\u{1b}[J\u{1b}[H") {
21 line = line.replace("\u{1b}[J\u{1b}[H", "");
22 if line.is_empty() {
23 return None;
24 }
25 }
26
27 if line.starts_with("\u{1b}[H") {
29 line = line.replace("\u{1b}[H", "");
30 if line.is_empty() {
31 return None;
32 }
33 }
34
35 if line.ends_with("\u{1b}[K") {
37 line = line.replace("\u{1b}[K", "").trim().to_string();
38 }
39
40 if line.trim().is_empty() {
42 return None;
43 }
44
45 if !line.starts_with('{') && !self.partial_line.is_empty() {
47 self.partial_line.push_str(&line);
48 line = self.partial_line.clone();
49 self.partial_line.clear();
50 } else if line.starts_with('{') && !line.ends_with('}') {
51 self.partial_line = line;
53 return None;
54 } else if !self.partial_line.is_empty() {
55 self.partial_line.push_str(&line);
57 line = self.partial_line.clone();
58 self.partial_line.clear();
59 }
60
61 if !line.starts_with('{') || !line.ends_with('}') {
63 return None;
64 }
65
66 Some(line)
67 }
68
69 pub fn is_screen_clear_event(line: &str) -> bool { line.starts_with("\u{1b}[J\u{1b}[H") }
71}