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}