1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use crate::enums::{Output};
use crate::parsers::parse_escape;

pub trait AnsiParser {
    fn ansi_parse(&self) -> AnsiParseIterator<'_>;
}

impl AnsiParser for str {
    fn ansi_parse(&self) -> AnsiParseIterator<'_> {
        AnsiParseIterator {
            dat: self
        }
    }
}

#[cfg(any(feature = "std", test))]
impl AnsiParser for String {
    fn ansi_parse(&self) -> AnsiParseIterator<'_> {
        AnsiParseIterator {
            dat: self
        }
    }
}

pub struct AnsiParseIterator<'a> {
    dat: &'a str,
}

impl<'a> Iterator for AnsiParseIterator<'a> {
    type Item = Output<'a>;
    
    fn next(&mut self) -> Option<Self::Item> {
        if self.dat == "" {
            return None;
        }

        let pos = self.dat.find('\u{1b}');
        if let Some(loc) = pos {
            if loc == 0 {
                let res = parse_escape(&self.dat[loc..]);

                if let Ok(ret) = res {
                    self.dat = &ret.0;
                    Some(Output::Escape(ret.1))
                }else{
                    let pos = self.dat[(loc+1)..].find('\u{1b}');
                    if let Some(loc) = pos {
                        //Added to because it's based one character ahead
                        let loc = loc+1;

                        let temp = &self.dat[..loc];
                        self.dat = &self.dat[loc..];

                        Some(Output::TextBlock(temp))
                    }else{
                        let temp = self.dat;
                        self.dat = "";

                        Some(Output::TextBlock(temp))
                    }
                }

            }else {
                let temp = &self.dat[..loc];
                self.dat = &self.dat[loc..];

                Some(Output::TextBlock(&temp))
            }
        }else{
            let temp = self.dat;
            self.dat = "";
            Some(Output::TextBlock(temp))
        }
    }
}