cas_parser/parser/ast/helper/
delimited.rs

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