at_commands/parser/
arguments_parser.rs1use {
17 crate::{
18 lowlevel::{Argument, Arguments, DelimitedArguments},
19 parser::common::{
20 next_match, next_match_one_of, next_match_option, next_match_rep, parse_string,
21 ParseResult,
22 },
23 },
24 pest::{iterators::Pair, RuleType},
25};
26
27pub struct ArgumentsParser<Rule: RuleType> {
28 pub argument_list: Rule,
29 pub argument: Rule,
30 pub arguments: Rule,
31 pub key_value_argument: Rule,
32 pub optional_argument_delimiter: Rule,
33 pub optional_argument_terminator: Rule,
34 pub parenthesized_argument_lists: Rule,
35 pub primitive_argument: Rule,
36}
37
38impl<Rule: RuleType> ArgumentsParser<Rule> {
39 #[allow(clippy::large_result_err)]
40 pub fn parse_delimited_arguments(
41 &self,
42 delimited_arguments: Pair<'_, Rule>,
43 ) -> ParseResult<DelimitedArguments, Rule> {
44 let mut delimited_arguments_elements = delimited_arguments.into_inner();
45
46 let delimited_argument_delimiter_option =
47 next_match_option(&mut delimited_arguments_elements, self.optional_argument_delimiter)?;
48 let parsed_delimited_argument_delimiter_option = match delimited_argument_delimiter_option {
49 Some(delimiter) => {
50 let string = parse_string(delimiter)?;
51 (!string.is_empty()).then_some(string)
52 }
53 None => None,
54 };
55
56 let arguments = next_match(&mut delimited_arguments_elements, self.arguments)?;
57 let parsed_arguments = self.parse_arguments(arguments)?;
58
59 let delimited_argument_terminator_option = next_match_option(
60 &mut delimited_arguments_elements,
61 self.optional_argument_terminator,
62 )?;
63 let parsed_delimited_argument_terminator_option = match delimited_argument_terminator_option
64 {
65 Some(terminator) => {
66 let string = parse_string(terminator)?;
67 (!string.is_empty()).then_some(string)
68 }
69 None => None,
70 };
71
72 Ok(DelimitedArguments {
73 delimiter: parsed_delimited_argument_delimiter_option,
74 arguments: parsed_arguments,
75 terminator: parsed_delimited_argument_terminator_option,
76 })
77 }
78
79 fn parse_arguments(&self, arguments: Pair<'_, Rule>) -> ParseResult<Arguments, Rule> {
80 let mut arguments_elements = arguments.into_inner();
81 let arguments_variant = next_match_one_of(
82 &mut arguments_elements,
83 vec![self.parenthesized_argument_lists, self.argument_list],
84 )?;
85 let arguments_variant_rule = arguments_variant.as_rule();
86 let parsed_arguments = if arguments_variant_rule == self.parenthesized_argument_lists {
87 self.parse_parenthesized_argument_lists(arguments_variant)?
88 } else if arguments_variant_rule == self.argument_list {
89 self.parse_argument_list(arguments_variant)?
90 } else {
91 unreachable!()
95 };
96
97 Ok(parsed_arguments)
98 }
99
100 fn parse_parenthesized_argument_lists(
101 &self,
102 parenthesized_argument_lists: Pair<'_, Rule>,
103 ) -> ParseResult<Arguments, Rule> {
104 let mut parenthesized_argument_lists_elements = parenthesized_argument_lists.into_inner();
105 let argument_list_vec =
106 next_match_rep(&mut parenthesized_argument_lists_elements, self.argument_list);
107
108 let parsed_argument_list_vec = argument_list_vec
109 .into_iter()
110 .map(|argument_list_pair| self.parse_argument_list_to_vec(argument_list_pair))
111 .collect::<ParseResult<Vec<Vec<Argument>>, Rule>>()?;
112
113 Ok(Arguments::ParenthesisDelimitedArgumentLists(parsed_argument_list_vec))
114 }
115
116 fn parse_argument_list(&self, argument_list: Pair<'_, Rule>) -> ParseResult<Arguments, Rule> {
117 let parsed_argument_list = self.parse_argument_list_to_vec(argument_list)?;
118 Ok(Arguments::ArgumentList(parsed_argument_list))
119 }
120
121 fn parse_argument_list_to_vec(
122 &self,
123 argument_list: Pair<'_, Rule>,
124 ) -> ParseResult<Vec<Argument>, Rule> {
125 let mut argument_list_elements = argument_list.into_inner();
126 let argument_vec = next_match_rep(&mut argument_list_elements, self.argument);
127
128 let parsed_argument_vec = argument_vec
129 .into_iter()
130 .map(|argument_pair| self.parse_argument(argument_pair))
131 .collect::<ParseResult<Vec<Argument>, Rule>>()?;
132
133 let parsed_argument_vec_maybe_empty =
140 if parsed_argument_vec == vec![Argument::PrimitiveArgument(String::from(""))] {
141 Vec::new()
142 } else {
143 parsed_argument_vec
144 };
145
146 Ok(parsed_argument_vec_maybe_empty)
147 }
148
149 fn parse_argument(&self, argument: Pair<'_, Rule>) -> ParseResult<Argument, Rule> {
150 let mut argument_elements = argument.into_inner();
151
152 let argument_variant = next_match_one_of(
153 &mut argument_elements,
154 vec![self.key_value_argument, self.primitive_argument],
155 )?;
156
157 let argument_variant_rule = argument_variant.as_rule();
158 let parsed_argument = if argument_variant_rule == self.key_value_argument {
159 self.parse_key_value_argument(argument_variant)?
160 } else if argument_variant_rule == self.primitive_argument {
161 Argument::PrimitiveArgument(parse_string(argument_variant)?)
162 } else {
163 unreachable!()
167 };
168
169 Ok(parsed_argument)
170 }
171
172 fn parse_key_value_argument(
173 &self,
174 key_value_argument: Pair<'_, Rule>,
175 ) -> ParseResult<Argument, Rule> {
176 let mut argument_elements = key_value_argument.into_inner();
177
178 let key = next_match(&mut argument_elements, self.primitive_argument)?;
179 let parsed_key = parse_string(key)?;
180
181 let value = next_match(&mut argument_elements, self.primitive_argument)?;
182 let parsed_value = parse_string(value)?;
183
184 Ok(Argument::KeyValueArgument { key: parsed_key, value: parsed_value })
185 }
186}