unsynn/
delimited.rs

1//! For easier composition we define the [`Delimited`] type here which is a `T`
2//! followed by a optional delimiting entity `D`. This is used by the
3//! [`DelimitedVec`] type to parse a list of entities separated by a delimiter.
4
5#![allow(clippy::module_name_repetitions)]
6
7#[allow(clippy::wildcard_imports)]
8use crate::*;
9
10/// This is used when one wants to parse a list of entities separated by delimiters. The
11/// delimiter is optional and can be `None` eg. when the entity is the last in the
12/// list. Usually the delimiter will be some simple punctuation token, but it is not limited
13/// to that.
14#[derive(Clone)]
15pub struct Delimited<T, D> {
16    /// The parsed value
17    pub value: T,
18    /// The optional delimiter
19    pub delimiter: Option<D>,
20}
21
22impl<T: Parse, D: Parse> Parser for Delimited<T, D> {
23    fn parser(tokens: &mut TokenIter) -> Result<Self> {
24        Ok(Self {
25            value: T::parser(tokens)?,
26            delimiter: Option::<D>::parser(tokens)?,
27        })
28    }
29}
30
31impl<T: ToTokens, D: ToTokens> ToTokens for Delimited<T, D> {
32    fn to_tokens(&self, tokens: &mut TokenStream) {
33        self.value.to_tokens(tokens);
34        self.delimiter.to_tokens(tokens);
35    }
36}
37
38#[mutants::skip]
39impl<T: std::fmt::Debug, D: std::fmt::Debug> std::fmt::Debug for Delimited<T, D> {
40    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
41        f.debug_struct(&format!(
42            "Delimited<{}, {}>",
43            std::any::type_name::<T>(),
44            std::any::type_name::<D>()
45        ))
46        .field("value", &self.value)
47        .field("delimiter", &self.delimiter)
48        .finish()
49    }
50}
51
52/// `T` followed by an optional `,`
53pub type CommaDelimited<T> = Delimited<T, Comma>;
54/// `T` followed by an optional `:`
55pub type ColonDelimited<T> = Delimited<T, Colon>;
56/// `T` followed by an optional `;`
57pub type SemicolonDelimited<T> = Delimited<T, Semicolon>;
58/// `T` followed by an optional `.`
59pub type DotDelimited<T> = Delimited<T, Dot>;
60/// `T` followed by an optional `::`
61pub type PathSepDelimited<T> = Delimited<T, PathSep>;