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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use crate::core::into_parser::IntoParser;
use crate::core::parser::Parser;
use crate::core::result::ParseResult;

#[derive(Debug, Clone, Copy)]
pub struct StringParser<ParserType> {
    parser: ParserType,
}

impl<ParserType> StringParser<ParserType> {
    pub fn new(parser: ParserType) -> Self {
        Self { parser: parser }
    }
}

impl<'a, ParserType> Parser<std::str::Chars<'a>> for StringParser<ParserType>
where
    ParserType: Parser<std::str::Chars<'a>>,
{
    type Output = (String,);

    fn parse(&self, it: std::str::Chars<'a>) -> ParseResult<Self::Output, std::str::Chars<'a>> {
        let i0 = it.clone();
        let res = self.parser.match_pattern(it);
        if let Some(_) = res.output {
            // this is length in bytes
            let len = i0.as_str().len() - res.it.as_str().len();
            ParseResult {
                // and this is byte slice casted to str
                output: Some((String::from(&i0.as_str()[..len]),)),
                it: res.it,
            }
        } else {
            ParseResult {
                output: None,
                it: res.it,
            }
        }
    }
    fn match_pattern(&self, it: std::str::Chars<'a>) -> ParseResult<(), std::str::Chars<'a>> {
        self.parser.match_pattern(it)
    }
}

impl<ParserType> IntoParser for StringParser<ParserType> {
    type Into = StringParser<ParserType>;
    fn into_parser(self) -> Self::Into {
        self
    }
}

pub fn string<ParserType>(parser: ParserType) -> StringParser<ParserType> {
    StringParser::new(parser)
}

#[derive(Debug, Clone, Copy)]
pub struct SliceParser<ParserType> {
    parser: ParserType,
}

impl<ParserType> SliceParser<ParserType> {
    pub fn new(parser: ParserType) -> Self {
        Self { parser: parser }
    }
}
impl<'a, T, ParserType> Parser<std::slice::Iter<'a, T>> for SliceParser<ParserType>
where
    ParserType: Parser<std::slice::Iter<'a, T>>,
    T: Clone,
{
    type Output = (Vec<T>,);

    fn parse(
        &self,
        it: std::slice::Iter<'a, T>,
    ) -> ParseResult<Self::Output, std::slice::Iter<'a, T>> {
        let i0 = it.clone();
        let res = self.parser.match_pattern(it);
        if let Some(_) = res.output {
            let len = i0.len() - res.it.len();
            ParseResult {
                output: Some((i0.as_slice()[..len].to_vec(),)),
                it: res.it,
            }
        } else {
            ParseResult {
                output: None,
                it: res.it,
            }
        }
    }
    fn match_pattern(
        &self,
        it: std::slice::Iter<'a, T>,
    ) -> ParseResult<(), std::slice::Iter<'a, T>> {
        self.parser.match_pattern(it)
    }
}

impl<ParserType> IntoParser for SliceParser<ParserType> {
    type Into = SliceParser<ParserType>;
    fn into_parser(self) -> Self::Into {
        self
    }
}

pub fn vec<ParserType>(parser: ParserType) -> SliceParser<ParserType> {
    SliceParser::new(parser)
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::{leaf::singlerange::SingleRangeParser, wrapper::seq::SeqParser};

    #[test]
    fn success1() {
        let digit_parser = SingleRangeParser::new('0'..='9');
        let digit_parser = SeqParser::new(digit_parser.clone(), digit_parser);
        let digit_parser = StringParser::new(digit_parser);

        let str = "123456abcd";
        let res = digit_parser.parse(str.chars());
        assert_eq!(res.output.unwrap(), ("12".to_string(),));
        assert_eq!(res.it.collect::<String>(), "3456abcd");
    }
    #[test]
    fn fail() {
        let digit_parser = SingleRangeParser::new('0'..='9');
        let digit_parser = SeqParser::new(digit_parser.clone(), digit_parser);
        let digit_parser = StringParser::new(digit_parser);

        let str = "ab3456abcd";
        let res = digit_parser.parse(str.chars());
        assert_eq!(res.output, None);
        assert_eq!(res.it.collect::<String>(), "ab3456abcd");
    }
}