yash_syntax/parser/
command.rs1use super::core::Parser;
23use super::core::Rec;
24use super::core::Result;
25use crate::syntax::Command;
26
27impl Parser<'_, '_> {
28 pub async fn command(&mut self) -> Result<Rec<Option<Command>>> {
33 match self.simple_command().await? {
34 Rec::AliasSubstituted => Ok(Rec::AliasSubstituted),
35 Rec::Parsed(None) => self
36 .full_compound_command()
37 .await
38 .map(|c| Rec::Parsed(c.map(Command::Compound))),
39 Rec::Parsed(Some(c)) => self
40 .short_function_definition(c)
41 .await
42 .map(|c| Rec::Parsed(Some(c))),
43 }
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use super::super::lex::Lexer;
50 use super::super::lex::TokenId::EndOfInput;
51 use super::*;
52 use assert_matches::assert_matches;
53 use futures_util::FutureExt;
54
55 #[test]
56 fn parser_command_simple() {
57 let mut lexer = Lexer::with_code("foo < bar");
58 let mut parser = Parser::new(&mut lexer);
59
60 let result = parser.command().now_or_never().unwrap();
61 let command = result.unwrap().unwrap().unwrap();
62 assert_matches!(command, Command::Simple(c) => {
63 assert_eq!(c.to_string(), "foo <bar");
64 });
65
66 let next = parser.peek_token().now_or_never().unwrap().unwrap();
67 assert_eq!(next.id, EndOfInput);
68 }
69
70 #[test]
71 fn parser_command_compound() {
72 let mut lexer = Lexer::with_code("(foo) < bar");
73 let mut parser = Parser::new(&mut lexer);
74
75 let result = parser.command().now_or_never().unwrap();
76 let command = result.unwrap().unwrap().unwrap();
77 assert_matches!(command, Command::Compound(c) => {
78 assert_eq!(c.to_string(), "(foo) <bar");
79 });
80
81 let next = parser.peek_token().now_or_never().unwrap().unwrap();
82 assert_eq!(next.id, EndOfInput);
83 }
84
85 #[test]
86 fn parser_command_function() {
87 let mut lexer = Lexer::with_code("fun () ( echo )");
88 let mut parser = Parser::new(&mut lexer);
89
90 let result = parser.command().now_or_never().unwrap();
91 let command = result.unwrap().unwrap().unwrap();
92 assert_matches!(command, Command::Function(f) => {
93 assert_eq!(f.to_string(), "fun() (echo)");
94 });
95
96 let next = parser.peek_token().now_or_never().unwrap().unwrap();
97 assert_eq!(next.id, EndOfInput);
98 }
99
100 #[test]
101 fn parser_command_eof() {
102 let mut lexer = Lexer::with_code("");
103 let mut parser = Parser::new(&mut lexer);
104
105 let result = parser.command().now_or_never().unwrap().unwrap();
106 assert_eq!(result, Rec::Parsed(None));
107 }
108}