cas_parser/parser/ast/helper/
delimited.rs

1use crate::parser::{error::Error, Parse, Parser};
2use std::marker::PhantomData;
3
4/// Represents zero or more values that are delimited by a certain token.
5#[derive(Debug, Clone, PartialEq, Eq)]
6pub struct Delimited<D, T> {
7    /// The values.
8    pub values: Vec<T>,
9
10    /// Marker type to allow using `D` as a type parameter.
11    delimiter: PhantomData<D>,
12}
13
14impl<'source, D, T> Parse<'source> for Delimited<D, T>
15where
16    D: Parse<'source> + std::fmt::Debug,
17    T: Parse<'source> + std::fmt::Debug,
18{
19    fn std_parse(
20        input: &mut Parser<'source>,
21        recoverable_errors: &mut Vec<Error>
22    ) -> Result<Self, Vec<Error>> {
23        let mut values = Vec::new();
24
25        loop {
26            // manually catch unrecoverable errors so we can parse zero values
27            let Ok(value) = input.try_parse().forward_errors(recoverable_errors) else {
28                break;
29            };
30            values.push(value);
31
32            if input.try_parse::<D>().forward_errors(recoverable_errors).is_err() {
33                break;
34            }
35        }
36
37        Ok(Self { values, delimiter: PhantomData })
38    }
39}