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 crate::alias::EmptyGlossary;
53 use crate::source::Source;
54 use assert_matches::assert_matches;
55 use futures_util::FutureExt;
56
57 #[test]
58 fn parser_command_simple() {
59 let mut lexer = Lexer::from_memory("foo < bar", Source::Unknown);
60 let mut parser = Parser::new(&mut lexer, &EmptyGlossary);
61
62 let result = parser.command().now_or_never().unwrap();
63 let command = result.unwrap().unwrap().unwrap();
64 assert_matches!(command, Command::Simple(c) => {
65 assert_eq!(c.to_string(), "foo <bar");
66 });
67
68 let next = parser.peek_token().now_or_never().unwrap().unwrap();
69 assert_eq!(next.id, EndOfInput);
70 }
71
72 #[test]
73 fn parser_command_compound() {
74 let mut lexer = Lexer::from_memory("(foo) < bar", Source::Unknown);
75 let mut parser = Parser::new(&mut lexer, &EmptyGlossary);
76
77 let result = parser.command().now_or_never().unwrap();
78 let command = result.unwrap().unwrap().unwrap();
79 assert_matches!(command, Command::Compound(c) => {
80 assert_eq!(c.to_string(), "(foo) <bar");
81 });
82
83 let next = parser.peek_token().now_or_never().unwrap().unwrap();
84 assert_eq!(next.id, EndOfInput);
85 }
86
87 #[test]
88 fn parser_command_function() {
89 let mut lexer = Lexer::from_memory("fun () ( echo )", Source::Unknown);
90 let mut parser = Parser::new(&mut lexer, &EmptyGlossary);
91
92 let result = parser.command().now_or_never().unwrap();
93 let command = result.unwrap().unwrap().unwrap();
94 assert_matches!(command, Command::Function(f) => {
95 assert_eq!(f.to_string(), "fun() (echo)");
96 });
97
98 let next = parser.peek_token().now_or_never().unwrap().unwrap();
99 assert_eq!(next.id, EndOfInput);
100 }
101
102 #[test]
103 fn parser_command_eof() {
104 let mut lexer = Lexer::from_memory("", Source::Unknown);
105 let mut parser = Parser::new(&mut lexer, &EmptyGlossary);
106
107 let result = parser.command().now_or_never().unwrap().unwrap();
108 assert_eq!(result, Rec::Parsed(None));
109 }
110}