1
2use crate::{base_traits::Parsable, error::parse_error::ParseError, iter::TokenIter, ConsumableToken};
3
4impl<P1, P2, T> Parsable<T> for (P1, P2)
5where
6 P1: Parsable<T>,
7 P2: Parsable<T>,
8 T: ConsumableToken,
9{
10 fn parse(iter: &mut TokenIter<T>) -> Result<Self, ParseError<T>>
11 where
12 Self: Sized,
13 {
14 Ok((iter.parse()?, iter.parse()?))
15 }
16
17 fn parse_if_match<F: Fn(&Self::ApplyMatchTo) -> bool>(
18 iter: &mut TokenIter<T>,
19 matches: F,
20 pattern: Option<&'static str>
21 ) -> Result<Self, ParseError<T>>
22 where
23 Self: Sized,
24 {
25 iter.try_do(|token_iter| {
26 let result = Self::parse(token_iter)?;
27 if matches(&result) {
28 Ok(result)
29 } else {
30 Err(ParseError::parsed_but_unmatching::<Self>(token_iter.current, &result,pattern))
32 }
33 })
34 }
35}
36
37impl<P1, P2, P3, T> Parsable<T> for (P1, P2, P3)
38where
39 P1: Parsable<T>,
40 P2: Parsable<T>,
41 P3: Parsable<T>,
42 T: ConsumableToken,
43{
44 fn parse(iter: &mut TokenIter<T>) -> Result<Self, ParseError<T>>
45 where
46 Self: Sized,
47 {
48 Ok((
49 iter.parse::<P1>()?,
50 iter.parse::<P2>()?,
51 iter.parse::<P3>()?,
52 ))
53 }
54
55 fn parse_if_match<F: Fn(&Self) -> bool>(
56 iter: &mut TokenIter<T>,
57 matches: F,
58 pattern: Option<&'static str>
59 ) -> Result<Self, ParseError<T>>
60 where
61 Self: Sized,
62 {
63 iter.try_do(|token_iter| {
64 let result = Self::parse(token_iter)?;
65 if matches(&result) {
66 Ok(result)
67 } else {
68 Err(ParseError::parsed_but_unmatching::<Self>(token_iter.current, &result,pattern))
70 }
71 })
72 }
73}
74
75impl<P1, P2, P3, P4, T> Parsable<T> for (P1, P2, P3, P4)
76where
77 P1: Parsable<T>,
78 P2: Parsable<T>,
79 P3: Parsable<T>,
80 P4: Parsable<T>,
81 T: ConsumableToken,
82{
83 fn parse(iter: &mut TokenIter<T>) -> Result<Self, ParseError<T>>
84 where
85 Self: Sized,
86 {
87 Ok((
88 iter.parse::<P1>()?,
89 iter.parse::<P2>()?,
90 iter.parse::<P3>()?,
91 iter.parse::<P4>()?,
92 ))
93 }
94}
95
96
97impl<T, P> Parsable<T> for Box<P>
100where
101 P: Parsable<T, ApplyMatchTo = P>,
102 T: ConsumableToken,
103{
104 type ApplyMatchTo = P;
105 fn parse(iter: &mut TokenIter<T>) -> Result<Self, ParseError<T>>
106 where
107 Self: Sized,
108 {
109 Ok(Box::new(P::parse(iter)?))
110 }
111
112 fn parse_if_match<F: Fn(&Self::ApplyMatchTo) -> bool>(
113 iter: &mut TokenIter<T>,
114 matches: F,
115 pattern: Option<&'static str>
116 ) -> Result<Self, ParseError<T>>
117 where
118 Self: Sized,
119 {
120 Ok(Box::new(iter.parse_if_match(matches, None)?))
121 }
122}
123
124impl<T, P> Parsable<T> for Vec<P>
125where
126 P: Parsable<T, ApplyMatchTo = P>,
127 T: ConsumableToken,
128{
129 type ApplyMatchTo = P;
130 fn parse(iter: &mut TokenIter<T>) -> Result<Self, ParseError<T>> {
131 let mut results = vec![];
132 while let Ok(r) = P::parse(iter) {
133 results.push(r);
134 }
135 Ok(results)
136 }
137
138 fn parse_if_match<F>(iter: &mut TokenIter<T>, matches: F, pattern: Option<&'static str>) -> Result<Vec<P>, ParseError<T>>
139 where
140 F: Fn(&Self::ApplyMatchTo) -> bool,
141 {
142 let mut result = vec![];
143 while let Ok(element) = iter.try_do(|token_iter| {
144 let result = Self::ApplyMatchTo::parse(token_iter);
145 match result {
146 Ok(aa) if matches(&aa) => Ok(aa),
147 Ok(found_but_unmatching) => {
148 Err(ParseError::parsed_but_unmatching::<Self::ApplyMatchTo>(token_iter.current, &found_but_unmatching,pattern))
149 }
150 Err(err) => Err(ParseError::from_conjunct_error::<Self::ApplyMatchTo>(err)),
151 }
152 }) {
153 result.push(element)
154 }
155 Ok(result)
156 }
157}
158
159impl<T, P> Parsable<T> for Option<P>
160where
161 P: Parsable<T, ApplyMatchTo = P>,
162 T: ConsumableToken,
163{
164 type ApplyMatchTo = P;
165 fn parse(iter: &mut TokenIter<T>) -> Result<Self, ParseError<T>> {
166 let r = iter.parse();
167 match r {
168 Ok(r) => Ok(Some(r)),
169 Err(_) => Ok(None),
170 }
171 }
172
173 fn parse_if_match<F: Fn(&Self::ApplyMatchTo) -> bool>(
174 iter: &mut TokenIter<T>,
175 matches: F,
176 pattern: Option<&'static str>
177 ) -> Result<Self, ParseError<T>>
178 where
179 Self: Sized,
180 {
181 let r: Result<Self::ApplyMatchTo, _> = iter.parse_if_match(matches, None);
182 match r {
183 Ok(r) => Ok(Some(r)),
184 Err(_) => Ok(None),
185 }
186 }
187}
188pub trait IfOk<T, E> {
189 fn if_ok(self, value: T) -> Result<T, E>;
190}
191
192impl<P, T, E> IfOk<T, E> for Result<P, E> {
193 fn if_ok(self, value: T) -> Result<T, E> {
194 match self {
195 Ok(_) => Ok(value),
196 Err(err) => Err(err),
197 }
198 }
199}
200
201#[cfg(test)]
202mod tests {
203
204 use crate::{
205 base_traits::Parsable, error::parse_error::ParseError, iter::TokenIter, t, token::Token,
206 };
207
208 #[derive(Debug, PartialEq, Clone)]
209 struct TestStruct {
210 ident: String,
211 semi: Option<Token>,
212 }
213
214 impl Parsable<Token> for TestStruct {
215 fn parse(iter: &mut TokenIter<Token>) -> Result<Self, ParseError<Token>>
216 where
217 Self: Sized,
218 {
219 let ident= match iter.parse_if_match(|tok|matches!(tok, Token::Identifier(_)), None)?{
220 Token::Identifier(string) => string,
221 _ => unreachable!("Domain error: token returned by parse_if_match should be of the same variant as the token passed as argument"),
222 };
223 let semi = <Option<Token> as Parsable<Token>>::parse_if_match(iter, |tok| {
224 matches!(tok, Token::SemiColon)
225 }, None)?;
226 Ok(TestStruct { ident, semi })
227 }
228 }
229
230 #[derive(Debug, PartialEq, Clone)]
231 struct VecStruct {
232 idents: Vec<Token>,
233 }
234
235 impl Parsable<Token> for VecStruct {
236 type ApplyMatchTo = Token;
237 fn parse(iter: &mut TokenIter<Token>) -> Result<Self, ParseError<Token>>
238 where
239 Self: Sized,
240 {
241 let idents = iter.parse_if_match(|tok| matches!(tok, Token::Identifier(_)), None)?;
242 Ok(VecStruct { idents })
243 }
244 fn parse_if_match<F: Fn(&Token) -> bool>(
245 iter: &mut TokenIter<Token>,
246 f: F,
247 pattern: Option<&'static str>
248 ) -> Result<Self, ParseError<Token>>
249 where
250 Self: Sized,
251 {
252 let idents = iter.parse_if_match(f, None)?;
253 Ok(VecStruct { idents })
254 }
255 }
256
257 #[derive(Debug, PartialEq, Clone)]
258 struct BoxStruct {
259 ident: Box<Token>,
260 }
261
262 impl Parsable<Token> for BoxStruct {
263 type ApplyMatchTo = Token;
264 fn parse(iter: &mut TokenIter<Token>) -> Result<Self, ParseError<Token>>
265 where
266 Self: Sized,
267 {
268 let ident = Box::parse(iter)?;
269 Ok(BoxStruct { ident })
270 }
271
272 fn parse_if_match<F: Fn(&Token) -> bool>(
273 iter: &mut TokenIter<Token>,
274 f: F,
275 pattern: Option<&'static str>
276 ) -> Result<Self, ParseError<Token>>
277 where
278 Self: Sized,
279 {
280 let ident = Box::parse_if_match(iter, f, None)?;
281 Ok(BoxStruct { ident })
282 }
283 }
284
285 #[test]
286 fn vec_of_tuples_arity2() {
287 let tokens = vec![t!(return), t!(litint 3), t!(return), t!(litint 3)];
288 let mut iter = TokenIter::new(tokens.clone());
289 let result: Vec<(Token, Token)> = iter.parse().unwrap();
290 assert_eq!(
291 result,
292 vec![
293 (
294 tokens.get(0).unwrap().clone(),
295 tokens.get(1).unwrap().clone()
296 ),
297 (
298 tokens.get(2).unwrap().clone(),
299 tokens.get(3).unwrap().clone()
300 )
301 ]
302 );
303
304 let tokens = vec![t!(return), t!(litint 3), t!(return)];
305 let mut iter = TokenIter::new(tokens.clone());
306 let result: Vec<(Token, Token)> = iter.parse().unwrap();
307 assert_eq!(
308 result,
309 vec![(
310 tokens.get(0).unwrap().clone(),
311 tokens.get(1).unwrap().clone()
312 ),]
313 );
314 }
315
316 #[test]
317 fn vec_of_tuples_arity3() {
318 let tokens = vec![
319 t!(return),
320 t!(litint 3),
321 t!(return),
322 t!(litint 3),
323 t!(return),
324 t!(litint 3),
325 ];
326 let mut iter = TokenIter::new(tokens.clone());
327 let result: Vec<(Token, Token, Token)> = iter.parse().unwrap();
328 assert_eq!(
329 result,
330 vec![
331 (
332 tokens.get(0).unwrap().clone(),
333 tokens.get(1).unwrap().clone(),
334 tokens.get(2).unwrap().clone(),
335 ),
336 (
337 tokens.get(3).unwrap().clone(),
338 tokens.get(4).unwrap().clone(),
339 tokens.get(5).unwrap().clone(),
340 )
341 ]
342 );
343
344 let tokens = vec![
345 t!(return),
346 t!(litint 3),
347 t!(return),
348 t!(litint 3),
349 t!(return),
350 ];
351 let mut iter = TokenIter::new(tokens.clone());
352 let result: Vec<(Token, Token, Token)> = iter.parse().unwrap();
353 assert_eq!(
354 result,
355 vec![(
356 tokens.get(0).unwrap().clone(),
357 tokens.get(1).unwrap().clone(),
358 tokens.get(2).unwrap().clone(),
359 ),]
360 );
361 }
362 #[test]
363 fn box_ok() {
364 let tokens = vec![t!(ident "hello")];
365 let result = BoxStruct::parse(&mut TokenIter::new(tokens)).unwrap();
366 assert_eq!(
367 result,
368 BoxStruct {
369 ident: Box::new(t!(ident "hello"))
370 }
371 );
372 }
373
374 #[test]
375 fn box_err() {
376 let tokens = vec![];
377 let result = BoxStruct::parse(&mut TokenIter::new(tokens));
378 assert!(result.is_err());
379 }
380
381 #[test]
382 fn box_match() {
383 let tokens = vec![t!(ident "hello")];
384 let result = BoxStruct::parse_if_match(&mut TokenIter::new(tokens), |t| {
385 matches!(t, Token::Identifier(_))
386 }, None);
387 assert!(result.is_ok());
388 }
389
390 #[test]
391 fn vec_parse_if_match() {
392 let tokens = vec![t!(ident "ident1"), t!(ident "ident2")];
393
394 let result = VecStruct::parse_if_match(&mut TokenIter::new(tokens), |tok| {
395 matches!(tok, Token::Identifier(_))
396 }, None)
397 .expect("Should be ok");
398 assert_eq!(
399 result.idents,
400 vec![
401 Token::Identifier("ident1".to_owned()),
402 Token::Identifier("ident2".to_owned())
403 ]
404 );
405 }
406
407 #[test]
408 fn parse_vec_with_many_elements() {
409 let tokens = vec![t!(ident "ident1"), t!(ident "ident2")];
410
411 let result = VecStruct::parse(&mut TokenIter::new(tokens)).expect("Should be ok");
412 assert_eq!(
413 result.idents,
414 vec![
415 Token::Identifier("ident1".to_owned()),
416 Token::Identifier("ident2".to_owned())
417 ]
418 );
419 }
420
421 #[test]
422 fn parse_vec_with_one_element() {
423 let tokens = vec![t!(ident "ident1")];
424
425 let result = VecStruct::parse(&mut TokenIter::new(tokens)).expect("Should be ok");
426 assert_eq!(result.idents, vec![Token::Identifier("ident1".to_owned())]);
427 }
428
429 #[test]
430 fn parse_vec_with_zero_elements() {
431 let tokens = vec![];
432
433 let result = VecStruct::parse(&mut TokenIter::new(tokens)).expect("Should be ok");
434 assert_eq!(result.idents, vec![]);
435 }
436
437 #[derive(Debug, Clone, PartialEq)]
438 struct ReturnStatement {
439 k_return: Option<Token>,
440 ident: Token,
441 semi: Option<Token>,
442 }
443
444 impl Parsable<Token> for ReturnStatement {
445 fn parse(iter: &mut TokenIter<Token>) -> Result<ReturnStatement, ParseError<Token>> {
446 let k_return = iter.parse_if_match(|input| matches!(input, Token::KReturn), None)?;
447 let ident = iter.parse_if_match(|input| matches!(input, Token::Identifier(_)), None)?;
448 let semi = iter.parse_if_match(|input| matches!(input, Token::SemiColon), None)?;
449 Ok(ReturnStatement {
450 k_return,
451 ident,
452 semi,
453 })
454 }
455 }
456
457 #[test]
458 fn test1() {
459 let tokens = vec![t!(return), t!(ident "some_ident"), t!(;)];
460 let expected = ReturnStatement {
461 k_return: Some(t!(return)),
462 ident: t!(ident "some_ident"),
463 semi: Some(t!(;)),
464 };
465
466 let result = ReturnStatement::parse(&mut TokenIter::new(tokens));
467 assert_eq!(Ok(expected), result);
468
469 let tokens = vec![t!(ident "some_ident"), t!(;)];
470 let expected = ReturnStatement {
471 k_return: None,
472 ident: t!(ident "some_ident"),
473 semi: Some(t!(;)),
474 };
475
476 let result = ReturnStatement::parse(&mut TokenIter::new(tokens));
477 assert_eq!(Ok(expected), result);
478
479 let tokens = vec![t!(return), t!(ident "some_ident")];
480
481 let expected = ReturnStatement {
482 k_return: Some(t!(return)),
483 ident: t!(ident "some_ident"),
484 semi: None,
485 };
486
487 let result = ReturnStatement::parse(&mut TokenIter::new(tokens));
488 assert_eq!(Ok(expected), result);
489 }
490
491 #[test]
492 fn parse_option_none() {
493 let tokens = vec![t!(ident "ident1")];
494
495 let result = TestStruct::parse(&mut TokenIter::new(tokens)).expect("Should be ok");
496 assert_eq!(result.ident, "ident1");
497 assert!(result.semi.is_none());
498 }
499
500 #[test]
501 fn parse_option_some() {
502 let tokens = vec![t!(ident "ident1"), t!(;)];
503
504 let result = TestStruct::parse(&mut TokenIter::new(tokens)).expect("Should be ok");
505 assert!(result.ident == "ident1");
506 assert!(result.semi == Some(Token::SemiColon));
507 }
508}