1use crate::enums::Output;
2use crate::parsers::parse_escape;
3
4pub trait AnsiParser {
5 fn ansi_parse(&self) -> AnsiParseIterator<'_>;
6}
7
8impl AnsiParser for str {
9 fn ansi_parse(&self) -> AnsiParseIterator<'_> {
10 AnsiParseIterator { dat: self }
11 }
12}
13
14#[cfg(any(feature = "std", test))]
15impl AnsiParser for String {
16 fn ansi_parse(&self) -> AnsiParseIterator<'_> {
17 AnsiParseIterator { dat: self }
18 }
19}
20
21#[derive(Debug)]
22pub struct AnsiParseIterator<'a> {
23 dat: &'a str,
24}
25
26impl<'a> Iterator for AnsiParseIterator<'a> {
27 type Item = Output<'a>;
28
29 fn next(&mut self) -> Option<Self::Item> {
30 if self.dat.is_empty() {
31 return None;
32 }
33
34 let pos = self.dat.find('\u{1b}');
35 if let Some(loc) = pos {
36 if loc == 0 {
37 let res = parse_escape(&self.dat[loc..]);
38
39 if let Ok(ret) = res {
40 self.dat = ret.0;
41 Some(Output::Escape(ret.1))
42 } else {
43 let pos = self.dat[(loc + 1)..].find('\u{1b}');
44 if let Some(loc) = pos {
45 let loc = loc + 1;
47
48 let temp = &self.dat[..loc];
49 self.dat = &self.dat[loc..];
50
51 Some(Output::TextBlock(temp))
52 } else {
53 let temp = self.dat;
54 self.dat = "";
55
56 Some(Output::TextBlock(temp))
57 }
58 }
59 } else {
60 let temp = &self.dat[..loc];
61 self.dat = &self.dat[loc..];
62
63 Some(Output::TextBlock(temp))
64 }
65 } else {
66 let temp = self.dat;
67 self.dat = "";
68 Some(Output::TextBlock(temp))
69 }
70 }
71}