pddlp/plan/
step.rs

1use super::{token::Token, Step};
2use crate::Result;
3use logos::Lexer;
4
5pub(super) fn parse<'a>(lexer: &mut Lexer<'a, Token<'a>>) -> Result<Step<'a>> {
6    let action = match lexer.next() {
7        Some(token) => match token {
8            Ok(Token::Name(name)) => name,
9            Ok(_) => return Err(("Unexpected Token", lexer.span())),
10            Err(_) => return Err(("Invalid Token", lexer.span())),
11        },
12        None => return Err(("Erroneous LParen", lexer.span())),
13    };
14    let objects = {
15        let mut objects = Vec::new();
16        let mut r_paren = false;
17
18        while let Some(token) = lexer.next() {
19            match token {
20                Ok(Token::Name(name)) => objects.push(name),
21                Ok(Token::RParen) => {
22                    r_paren = true;
23                    break;
24                }
25                Ok(_) => return Err(("Unexpected Token", lexer.span())),
26                Err(_) => return Err(("Invalid Token", lexer.span())),
27            }
28        }
29
30        if !r_paren {
31            return Err(("Missing RParen", lexer.span()));
32        }
33
34        objects
35    };
36    Ok(Step { action, objects })
37}
38
39#[cfg(test)]
40mod test {
41    use super::{Result, Step, Token};
42    use logos::Logos;
43    use rstest::rstest;
44
45    #[rstest]
46    #[case(Ok(crate::plan::Step { action: "a", objects: vec![] }), "a)")]
47    #[case(Ok(crate::plan::Step { action: "a", objects: vec!["b"] }), "a b)")]
48    #[case(Ok(crate::plan::Step { action: "a", objects: vec!["b", "c"] }), "a b c)")]
49    #[case(Err(("Missing RParen", 1..1)), "a")]
50    #[case(Err(("Unexpected Token", 0..1)), ")")]
51    fn parse(#[case] expected: Result<Step>, #[case] input: &str) {
52        let mut lexer = Token::lexer(input);
53        assert_eq!(expected, super::parse(&mut lexer));
54    }
55}