sic_parser/
lib.rs

1#![deny(clippy::all)]
2#![allow(clippy::unnecessary_wraps, clippy::upper_case_acronyms)]
3
4#[macro_use]
5extern crate pest_derive;
6
7#[cfg(test)]
8#[macro_use]
9extern crate parameterized;
10
11use pest::Parser;
12
13use crate::errors::SicParserError;
14use crate::rule_parser::parse_image_operations;
15use sic_image_engine::engine::Instr;
16
17pub mod errors;
18pub mod named_value;
19pub mod rule_parser;
20pub mod value_parser;
21
22const PARSER_RULE: Rule = Rule::main;
23
24#[derive(Parser)]
25#[grammar = "grammar.pest"]
26pub struct SICParser;
27
28pub fn parse_script(script: &str) -> Result<Vec<Instr>, SicParserError> {
29    let parsed_script = SICParser::parse(PARSER_RULE, script);
30
31    parsed_script
32        .map_err(|err| SicParserError::PestGrammarError(err.to_string()))
33        .and_then(parse_image_operations)
34}
35
36#[cfg(test)]
37mod tests {
38    use sic_image_engine::ImgOp;
39    use sic_image_engine::engine::Instr;
40
41    use super::*;
42
43    #[test]
44    fn test_too_many_args() {
45        let input = "blur 15 28;";
46        let parsed = SICParser::parse(Rule::main, input);
47
48        // Manually constructing a pest::Error::ParsingError is a hell, because of Position, which,
49        // except for the from_start() method is private.
50        assert!(parsed.is_err());
51    }
52
53    #[test]
54    fn test_parsed() {
55        let input = "blur 15; flip-vertical";
56        let parsed = parse_script(input);
57
58        assert!(parsed.is_ok());
59
60        assert_eq!(
61            parsed.unwrap(),
62            vec![
63                Instr::Operation(ImgOp::Blur(15.0)),
64                Instr::Operation(ImgOp::FlipVertical)
65            ]
66        );
67    }
68
69    #[test]
70    fn test_parsed_fail() {
71        let input = "blur 15.7.; flipv";
72        let parsed = parse_script(input);
73
74        assert!(parsed.is_err());
75    }
76}