topdown/
keyword.rs

1use super::{CharSeq, ParserResult, Parser, Succ, Error, Fail};
2
3pub struct Keyword<'a> {
4    keyword: &'a str,
5}
6
7static ASCII_LETTERS: &'static str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
8
9pub fn keyword<'a>(k: &'a str) -> Keyword {
10    return Keyword{keyword: k};
11}
12
13impl<'a> Parser<String> for Keyword<'a> {
14    fn parse(&self, cs: &mut CharSeq) -> ParserResult<String> {
15        let h = cs.enable_hook;
16        cs.enable_hook = false;
17        match cs.accept(&self.keyword) {
18            Succ(r) => {
19                cs.enable_hook = h;
20                if ASCII_LETTERS.contains(cs.current()) {
21                    return cs.fail(cs.current().to_string().as_str());
22                }
23                if cs.enable_hook {
24                    cs.do_hook();
25                }
26                Succ(r)
27            },
28            Fail(m, l) => {cs.enable_hook = h; Fail(m, l)},
29            Error(m, l) => {cs.enable_hook = h; Error(m, l)}
30        }
31    }
32
33    #[allow(unused_variables)]
34    fn _parse(&self, cs: &mut CharSeq) -> ParserResult<String> {
35        return Succ("".to_string()); // unused
36    }
37}
38
39#[cfg(test)]
40#[allow(unused_variables)]
41#[allow(unused_imports)]
42mod tests {
43    use super::keyword;
44    use super::super::{CharSeq, skip, ParserResult, Parser, Succ, Fail, Error};
45
46    #[test]
47    fn test_keyword() {
48        let mut cs = CharSeq::new("keyword keywordxxx", "");
49        let k = keyword("keyword");
50        let s = skip(" ");
51        cs.add_hook(&s);
52        match cs.accept(&k) {
53            Succ(r) => (),
54            _ => assert!(false)
55        }
56        match cs.accept(&k) {
57            Fail(m, l) => (),
58            _ => assert!(false)
59        }
60    }
61
62}