open_pql/range_parser/
mod.rs

1use std::convert::From;
2
3use ast::Expr;
4pub use error::Error;
5use error::{LalrError, ResultE};
6use lalrpop_util::{lalrpop_mod, lexer::Token, ParseError};
7
8use crate::{Loc, LocInfo};
9
10pub mod ast;
11mod error;
12
13lalrpop_mod!(
14    #[allow(clippy::empty_line_after_outer_attr)]
15    #[allow(clippy::iter_nth_zero)]
16    #[allow(clippy::nursery)]
17    #[allow(clippy::pedantic)]
18    #[allow(clippy::restriction)]
19    #[allow(clippy::useless_conversion)]
20    parser,
21    "/range_parser/range.rs"
22);
23
24type Expected = Vec<String>;
25
26pub fn parse(src: &str) -> Result<Box<Expr>, Error> {
27    Ok(parser::ExprParser::new().parse(src)?)
28}
29
30#[cfg_attr(coverage_nightly, coverage(off))]
31#[cfg(test)]
32pub mod tests {
33    use super::*;
34
35    pub fn parse_card(src: &str) -> ResultE<ast::RangeCard> {
36        parser::RangeCardParser::new().parse(src)
37    }
38
39    pub fn parse_list(src: &str) -> ResultE<ast::List> {
40        parser::ListParser::new().parse(src)
41    }
42
43    pub fn parse_span(src: &str) -> ResultE<ast::Span> {
44        parser::SpanParser::new().parse(src)
45    }
46
47    pub fn parse_term(src: &str) -> ResultE<ast::Term> {
48        parser::TermParser::new().parse(src)
49    }
50
51    fn assert_str_in(vec: &[String], val: &str) {
52        assert!(vec.contains(&format!("\"{val}\"")));
53    }
54
55    #[test]
56    fn test_error_invalid_token() {
57        assert_eq!(Error::InvalidToken((0, 1)), parse("?").unwrap_err());
58    }
59
60    #[test]
61    fn test_error_unrecognized_eof() {
62        let res = parse("[").unwrap_err();
63
64        if let Error::UnrecognizedEof(loc, expected) = res {
65            assert_eq!(loc, (1, 2));
66            assert_eq!(expected.len(), 3);
67
68            assert_str_in(&expected, "Suit");
69            assert_str_in(&expected, "Rank");
70            assert_str_in(&expected, "RankSuit");
71        } else {
72            panic!("Expected: UnrecognizedEof. Got: {res:?}")
73        }
74    }
75
76    #[test]
77    fn test_error_unrecognized_token() {
78        let res = parse("[,").unwrap_err();
79
80        if let Error::UnrecognizedToken(loc, expected) = res {
81            assert_eq!(loc, (1, 2));
82            assert_eq!(expected.len(), 3);
83
84            assert_str_in(&expected, "Suit");
85            assert_str_in(&expected, "Rank");
86            assert_str_in(&expected, "RankSuit");
87        } else {
88            panic!("Expected: UnrecognizedToken. Got: {res:?}")
89        }
90    }
91
92    #[test]
93    fn test_error() {
94        let err = LalrError::ExtraToken {
95            token: (0, Token(0, "a"), 1),
96        };
97
98        assert_eq!(Error::ExtraToken((0, 1)), err.into());
99
100        let err = LalrError::User {
101            error: Error::InvalidRank((0, 1)),
102        };
103
104        assert_eq!(Error::InvalidRank((0, 1)), err.into());
105    }
106}