astray_core/
impl_std.rs

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                // TODO: Error messages
31                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                // TODO: Error messages
69                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
97// TODO: macro for tuple implementation
98
99impl<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}