wp_primitives/fun/
parser.rs1use std::net::IpAddr;
2
3use crate::fun::fun_trait::{Fun0Builder, Fun1Builder, Fun2Builder};
4use crate::net::ip;
5use crate::symbol::{symbol_bracket_beg, symbol_bracket_end, symbol_comma};
6use winnow::ascii::{digit1, multispace0};
7use winnow::combinator::separated;
8use winnow::{ModalResult as WResult, Parser};
9
10use super::fun_trait::ParseNext;
11
12pub fn take_call_args2<T: Fun2Builder>(data: &mut &str) -> WResult<(T::ARG1, T::ARG2)> {
13 multispace0.parse_next(data)?;
14 symbol_bracket_beg.parse_next(data)?;
15 multispace0.parse_next(data)?;
16 let a1 = T::args1.parse_next(data)?;
17 (multispace0, symbol_comma, multispace0).parse_next(data)?;
18 let a2 = T::args2.parse_next(data)?;
19 multispace0.parse_next(data)?;
20 symbol_bracket_end.parse_next(data)?;
21 Ok((a1, a2))
22}
23
24pub fn take_call_args0<T: Fun0Builder>(data: &mut &str) -> WResult<()> {
25 multispace0.parse_next(data)?;
26 symbol_bracket_beg.parse_next(data)?;
27 multispace0.parse_next(data)?;
28 symbol_bracket_end.parse_next(data)?;
29 Ok(())
30}
31
32pub fn take_call_args1<T: Fun1Builder>(data: &mut &str) -> WResult<T::ARG1> {
33 multispace0.parse_next(data)?;
34 symbol_bracket_beg.parse_next(data)?;
35 multispace0.parse_next(data)?;
36 let a1 = T::args1.parse_next(data)?;
37 multispace0.parse_next(data)?;
38 symbol_bracket_end.parse_next(data)?;
39 Ok(a1)
40}
41
42pub fn call_fun_args2<T: Fun2Builder>(data: &mut &str) -> WResult<T> {
43 T::fun_name().parse_next(data)?;
44 let args = take_call_args2::<T>.parse_next(data)?;
45 let obj = T::build(args);
46 Ok(obj)
47}
48
49pub fn call_fun_args1<T: Fun1Builder>(data: &mut &str) -> WResult<T> {
50 T::fun_name().parse_next(data)?;
51 let args = take_call_args1::<T>.parse_next(data)?;
52 let obj = T::build(args);
53 Ok(obj)
54}
55
56pub fn call_fun_args0<T: Fun0Builder>(data: &mut &str) -> WResult<T> {
57 T::fun_name().parse_next(data)?;
58 take_call_args0::<T>.parse_next(data)?;
59 let obj = T::build();
60 Ok(obj)
61}
62
63pub fn take_arr<T: ParseNext<T>>(data: &mut &str) -> WResult<Vec<T>> {
64 (multispace0, "[", multispace0).parse_next(data)?;
65 let arr: Vec<T> = separated(1.., T::parse_next, ",").parse_next(data)?;
66 (multispace0, "]").parse_next(data)?;
67 Ok(arr)
68}
69
70impl ParseNext<u32> for u32 {
71 fn parse_next(input: &mut &str) -> WResult<u32> {
72 use winnow::error::{ErrMode, ParserError};
73 let str = digit1(input)?;
74 str.parse::<u32>().map_err(|_| ErrMode::from_input(input))
75 }
76}
77
78impl ParseNext<i64> for i64 {
79 fn parse_next(input: &mut &str) -> WResult<i64> {
80 use winnow::error::{ErrMode, ParserError};
81 let str = digit1(input)?;
82 str.parse::<i64>().map_err(|_| ErrMode::from_input(input))
83 }
84}
85impl ParseNext<IpAddr> for IpAddr {
86 fn parse_next(input: &mut &str) -> WResult<IpAddr> {
87 ip.parse_next(input)
88 }
89}
90
91#[cfg(test)]
92mod test {
93 use super::{call_fun_args1, take_arr};
94 use crate::fun::fun_trait::Fun1Builder;
95 use winnow::{
96 ModalResult as WResult,
98 Parser,
99 };
100
101 #[derive(Debug, PartialEq)]
102 struct A {
103 arr: Vec<u32>,
104 }
105 impl Fun1Builder for A {
106 type ARG1 = Vec<u32>;
107
108 fn args1(data: &mut &str) -> WResult<Self::ARG1> {
109 take_arr::<u32>(data)
110 }
111
112 fn fun_name() -> &'static str {
113 "fun_a"
114 }
115
116 fn build(args: Self::ARG1) -> Self {
117 A { arr: args }
118 }
119 }
120
121 #[test]
122 fn test_arr_args_fun() -> WResult<()> {
123 let mut data = "fun_a([1,2,3])";
124 let x = call_fun_args1::<A>.parse_next(&mut data)?;
125 println!("{:?}", x);
126 assert_eq!(x, A { arr: vec![1, 2, 3] });
127 Ok(())
128 }
129
130 mod u32_parsing {
135 use super::super::ParseNext;
136
137 #[test]
138 fn valid_u32_parsing() {
139 let mut input = "123";
140 let result = u32::parse_next(&mut input);
141 assert!(result.is_ok());
142 assert_eq!(result.unwrap(), 123);
143 }
144
145 #[test]
146 fn valid_u32_max_value() {
147 let mut input = "4294967295"; let result = u32::parse_next(&mut input);
149 assert!(result.is_ok());
150 assert_eq!(result.unwrap(), u32::MAX);
151 }
152
153 #[test]
154 fn invalid_u32_overflow() {
155 let mut input = "4294967296"; let result = u32::parse_next(&mut input);
157 assert!(result.is_err(), "Should fail on u32 overflow");
158 }
159
160 #[test]
161 fn invalid_u32_negative() {
162 let mut input = "-1";
163 let result = u32::parse_next(&mut input);
164 assert!(result.is_err(), "Should fail on negative number for u32");
165 }
166
167 #[test]
168 fn invalid_u32_non_numeric() {
169 let mut input = "abc";
170 let result = u32::parse_next(&mut input);
171 assert!(result.is_err(), "Should fail on non-numeric input");
172 }
173
174 #[test]
175 fn empty_input() {
176 let mut input = "";
177 let result = u32::parse_next(&mut input);
178 assert!(result.is_err(), "Should fail on empty input");
179 }
180 }
181
182 mod i64_parsing {
183 use super::super::ParseNext;
184
185 #[test]
186 fn valid_i64_positive() {
187 let mut input = "123";
188 let result = i64::parse_next(&mut input);
189 assert!(result.is_ok());
190 assert_eq!(result.unwrap(), 123);
191 }
192
193 #[test]
194 fn valid_i64_max_value() {
195 let mut input = "9223372036854775807"; let result = i64::parse_next(&mut input);
197 assert!(result.is_ok());
198 assert_eq!(result.unwrap(), i64::MAX);
199 }
200
201 #[test]
202 fn invalid_i64_overflow() {
203 let mut input = "9223372036854775808"; let result = i64::parse_next(&mut input);
205 assert!(result.is_err(), "Should fail on i64 overflow");
206 }
207
208 #[test]
209 fn invalid_i64_negative() {
210 let mut input = "-123";
212 let result = i64::parse_next(&mut input);
213 assert!(
214 result.is_err(),
215 "Should fail on negative (digit1 doesn't match '-')"
216 );
217 }
218
219 #[test]
220 fn invalid_i64_non_numeric() {
221 let mut input = "xyz";
222 let result = i64::parse_next(&mut input);
223 assert!(result.is_err(), "Should fail on non-numeric input");
224 }
225 }
226
227 mod array_parsing {
228 use super::super::take_arr;
229
230 #[test]
231 fn valid_array_single_element() {
232 let mut input = "[42]";
233 let result = take_arr::<u32>(&mut input);
234 assert!(result.is_ok());
235 assert_eq!(result.unwrap(), vec![42]);
236 }
237
238 #[test]
239 fn valid_array_multiple_elements() {
240 let mut input = "[1,2,3,4,5]";
241 let result = take_arr::<u32>(&mut input);
242 assert!(result.is_ok());
243 assert_eq!(result.unwrap(), vec![1, 2, 3, 4, 5]);
244 }
245
246 #[test]
247 fn valid_array_with_spaces() {
248 let mut input = "[1,2,3]"; let result = take_arr::<u32>(&mut input);
250 assert!(result.is_ok());
251 assert_eq!(result.unwrap(), vec![1, 2, 3]);
252 }
253
254 #[test]
255 fn invalid_array_missing_bracket() {
256 let mut input = "1,2,3]";
257 let result = take_arr::<u32>(&mut input);
258 assert!(result.is_err(), "Should fail on missing opening bracket");
259 }
260
261 #[test]
262 fn invalid_array_empty() {
263 let mut input = "[]";
264 let result = take_arr::<u32>(&mut input);
265 assert!(result.is_err(), "Should fail on empty array");
267 }
268
269 #[test]
270 fn invalid_array_trailing_comma() {
271 let mut input = "[1,2,]";
272 let result = take_arr::<u32>(&mut input);
273 assert!(result.is_err(), "Should fail on trailing comma");
274 }
275 }
276
277 mod function_call_parsing {
278 use super::{super::call_fun_args1, A};
279
280 #[test]
281 fn valid_function_call() {
282 let mut input = "fun_a([1,2,3])";
283 let result = call_fun_args1::<A>(&mut input);
284 assert!(result.is_ok());
285 assert_eq!(result.unwrap(), A { arr: vec![1, 2, 3] });
286 }
287
288 #[test]
289 fn valid_function_call_with_spaces() {
290 let mut input = "fun_a([1,2,3])"; let result = call_fun_args1::<A>(&mut input);
292 assert!(result.is_ok());
293 assert_eq!(result.unwrap(), A { arr: vec![1, 2, 3] });
294 }
295
296 #[test]
297 fn invalid_function_wrong_name() {
298 let mut input = "fun_b([1,2,3])";
299 let result = call_fun_args1::<A>(&mut input);
300 assert!(result.is_err(), "Should fail on wrong function name");
301 }
302
303 #[test]
304 fn invalid_function_missing_parens() {
305 let mut input = "fun_a[1,2,3]";
306 let result = call_fun_args1::<A>(&mut input);
307 assert!(result.is_err(), "Should fail on missing parentheses");
308 }
309
310 #[test]
311 fn invalid_function_empty_args() {
312 let mut input = "fun_a()";
313 let result = call_fun_args1::<A>(&mut input);
314 assert!(result.is_err(), "Should fail on empty arguments");
315 }
316 }
317}