unsynn/
container.rs

1//! This module provides parsers for types that contain possibly multiple values. This
2//! includes stdlib types like [`Option`], [`Vec`], [`Box`], [`Rc`], [`RefCell`] and types
3//! for delimited and repeated values with numbered repeats.
4
5use crate::{
6    Colon, Comma, Delimited, Dot, Error, Nothing, Parse, Parser, PathSep, Result, Semicolon,
7    ToTokens, TokenIter, TokenStream,
8};
9
10use std::{cell::RefCell, rc::Rc};
11
12/// Zero or One of T.
13impl<T: Parse> Parser for Option<T> {
14    fn parser(tokens: &mut TokenIter) -> Result<Self> {
15        match T::parse(tokens) {
16            Ok(value) => Ok(Some(value)),
17            Err(_) => Ok(None),
18        }
19    }
20}
21
22impl<T: ToTokens> ToTokens for Option<T> {
23    fn to_tokens(&self, tokens: &mut TokenStream) {
24        if let Some(t) = self.as_ref() {
25            t.to_tokens(tokens);
26        }
27    }
28}
29
30/// Any number of T
31impl<T: Parse> Parser for Vec<T> {
32    fn parser(tokens: &mut TokenIter) -> Result<Self> {
33        let mut output = Vec::new();
34        while let Ok(value) = T::parse(tokens) {
35            output.push(value);
36        }
37        Ok(output)
38    }
39}
40
41impl<T: ToTokens> ToTokens for Vec<T> {
42    fn to_tokens(&self, tokens: &mut TokenStream) {
43        self.iter().for_each(|value| value.to_tokens(tokens));
44    }
45}
46
47/// A trait for parsing a repeating `T` with a minimum and maximum limit.
48/// Sometimes the number of elements to be parsed is determined at runtime eg. a number of
49/// header items needs a matching number of values.
50///
51/// # Example
52///
53/// Parse at table with a number of headers followed by values.
54///
55/// ```
56/// # use unsynn::*;
57/// let mut token_iter = "
58///     foo:       bar:
59///     foo_value  bar_value
60/// ".to_token_iter();
61///
62/// let headers = Vec::<Cons<Ident,Colon>>::parse(&mut token_iter).unwrap();
63/// let values = Vec::<Ident>::parse_exactly(&mut token_iter, headers.len()).unwrap();
64/// ```
65#[allow(clippy::missing_errors_doc)]
66pub trait RangedRepeats: Sized {
67    /// Parse at least `min` and up to `max` (inclusive) elements.
68    fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self>;
69
70    /// Parse any number of elements.
71    fn parse_any(tokens: &mut TokenIter) -> Result<Self> {
72        Self::parse_repeats(tokens, 0, usize::MAX)
73    }
74
75    /// Parse at least one element.
76    fn parse_many(tokens: &mut TokenIter) -> Result<Self> {
77        Self::parse_repeats(tokens, 1, usize::MAX)
78    }
79
80    /// Parse zero or one element.
81    fn parse_optional(tokens: &mut TokenIter) -> Result<Self> {
82        Self::parse_repeats(tokens, 0, 1)
83    }
84
85    /// Parse exactly `n` elements.
86    fn parse_exactly(tokens: &mut TokenIter, n: usize) -> Result<Self> {
87        Self::parse_repeats(tokens, n, n)
88    }
89
90    /// Parse at most `n` elements.
91    fn parse_at_most(tokens: &mut TokenIter, n: usize) -> Result<Self> {
92        Self::parse_repeats(tokens, 0, n)
93    }
94
95    /// Parse at least `n` elements.
96    fn parse_at_least(tokens: &mut TokenIter, n: usize) -> Result<Self> {
97        Self::parse_repeats(tokens, n, usize::MAX)
98    }
99}
100
101impl<T: Parse> RangedRepeats for Vec<T> {
102    fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self> {
103        let mut output = Vec::with_capacity(min);
104        for _ in 0..max {
105            if let Ok(value) = T::parse(tokens) {
106                output.push(value);
107            } else {
108                break;
109            }
110        }
111
112        if output.len() >= min {
113            Ok(output)
114        } else {
115            Error::other(
116                tokens,
117                format!("less than {} elements, got {}", min, output.len()),
118            )
119        }
120    }
121}
122
123/// Box a parseable entity. In a enum it may happen that most variants are rather small while
124/// few variants are large. In this case it may be beneficial to box the large variants to
125/// keep the enum lean. `Box` or `Rc` are required for parsing recursive grammars.
126impl<T: Parse> Parser for Box<T> {
127    fn parser(tokens: &mut TokenIter) -> Result<Self> {
128        Ok(Box::new(T::parser(tokens)?))
129    }
130}
131
132impl<T: ToTokens> ToTokens for Box<T> {
133    fn to_tokens(&self, tokens: &mut TokenStream) {
134        self.as_ref().to_tokens(tokens);
135    }
136}
137
138/// Rc a parseable entity. Just because we can. Sometimes when a value is shared between
139/// multiple entities it may be beneficial to use Rc. `Box` or `Rc` are required for parsing recursive grammars.
140impl<T: Parse> Parser for Rc<T> {
141    fn parser(tokens: &mut TokenIter) -> Result<Self> {
142        Ok(Rc::new(T::parser(tokens)?))
143    }
144}
145
146impl<T: ToTokens> ToTokens for Rc<T> {
147    fn to_tokens(&self, tokens: &mut TokenStream) {
148        self.as_ref().to_tokens(tokens);
149    }
150}
151
152/// Put any parseable entity in a `RefCell`. In case one wants to mutate the a parse tree on the
153/// fly.
154impl<T: Parse> Parser for RefCell<T> {
155    fn parser(tokens: &mut TokenIter) -> Result<Self> {
156        Ok(RefCell::new(T::parser(tokens)?))
157    }
158}
159
160impl<T: ToTokens> ToTokens for RefCell<T> {
161    fn to_tokens(&self, tokens: &mut TokenStream) {
162        self.borrow().to_tokens(tokens);
163    }
164}
165
166/// A `Vec<T>` that is filled up to the first appearance of an terminating `S`.  This `S` may
167/// be a subset of `T`, thus parsing become lazy.  This is the same as
168/// `Cons<Vec<Cons<Except<S>,T>>,S>` but more convenient and efficient.
169///
170/// # Example
171///
172/// Parse anything until a `;`.
173///
174/// ```
175/// # use unsynn::*;
176/// let mut token_iter = "foo bar ; baz ;".to_token_iter();
177///
178/// type Example = LazyVec<TokenTree, Semicolon>;
179///
180/// let _example = Example::parse(&mut token_iter).unwrap();
181/// let _example = Example::parse(&mut token_iter).unwrap();
182/// ```
183#[derive(Clone)]
184pub struct LazyVec<T, S> {
185    /// The vector of repeating `T`
186    pub vec: Vec<T>,
187    /// The terminating `S`
188    pub terminator: S,
189}
190
191impl<T: Parse, S: Parse> Parser for LazyVec<T, S> {
192    fn parser(tokens: &mut TokenIter) -> Result<Self> {
193        let mut vec = Vec::new();
194
195        loop {
196            if let Ok(terminator) = S::parse(tokens) {
197                return Ok(Self { vec, terminator });
198            }
199
200            vec.push(T::parse(tokens)?);
201        }
202    }
203}
204
205impl<T: ToTokens, S: ToTokens> ToTokens for LazyVec<T, S> {
206    fn to_tokens(&self, tokens: &mut TokenStream) {
207        self.vec.iter().for_each(|value| value.to_tokens(tokens));
208        self.terminator.to_tokens(tokens);
209    }
210}
211
212impl<T: Parse, S: Parse> RangedRepeats for LazyVec<T, S> {
213    fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self> {
214        let mut vec = Vec::with_capacity(min);
215        for _ in 0..max {
216            if let Ok(terminator) = S::parse(tokens) {
217                return if vec.len() >= min {
218                    Ok(Self { vec, terminator })
219                } else {
220                    Error::other(
221                        tokens,
222                        format!("less than {} elements, got {}", min, vec.len()),
223                    )
224                };
225            }
226            vec.push(T::parse(tokens)?);
227        }
228        Error::other(tokens, format!("more than {max} elements"))
229    }
230}
231
232impl<T, S> IntoIterator for LazyVec<T, S> {
233    type Item = T;
234    type IntoIter = std::vec::IntoIter<Self::Item>;
235
236    fn into_iter(self) -> Self::IntoIter {
237        self.vec.into_iter()
238    }
239}
240
241#[mutants::skip]
242impl<T: std::fmt::Debug, S: std::fmt::Debug> std::fmt::Debug for LazyVec<T, S> {
243    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
244        f.debug_struct(&format!(
245            "LazyVec<{}, {}>",
246            std::any::type_name::<T>(),
247            std::any::type_name::<S>()
248        ))
249        .field("vec", &self.vec)
250        .field("terminator", &self.terminator)
251        .finish()
252    }
253}
254
255/// Since the delimiter in [`Delimited<T,D>`] is optional a [`Vec<Delimited<T,D>>`] would parse
256/// consecutive values even without delimiters. [`DelimitedVec<T,D>`] will stop parsing after
257/// the first value without a delimiter.
258#[derive(Clone)]
259pub struct DelimitedVec<T, D>(pub Vec<Delimited<T, D>>);
260
261impl<T: Parse, D: Parse> Parser for DelimitedVec<T, D> {
262    fn parser(tokens: &mut TokenIter) -> Result<Self> {
263        let mut output = Vec::new();
264        while let Ok(delimited) = Delimited::<T, D>::parse(tokens) {
265            let done = delimited.delimiter.is_none();
266            output.push(delimited);
267            if done {
268                break;
269            }
270        }
271        Ok(Self(output))
272    }
273}
274
275/// Converts a [`DelimitedVec<T, D>`] into a [`Vec<T>`].
276/// This loses all delimiters, which may have been stateful (`Either` or other enums).
277impl<T, D> From<DelimitedVec<T, D>> for Vec<T> {
278    fn from(delimited_vec: DelimitedVec<T, D>) -> Self {
279        delimited_vec
280            .0
281            .into_iter()
282            .map(|delimited| delimited.value)
283            .collect()
284    }
285}
286
287impl<T: ToTokens, D: ToTokens> ToTokens for DelimitedVec<T, D> {
288    fn to_tokens(&self, tokens: &mut TokenStream) {
289        self.0.iter().for_each(|value| value.to_tokens(tokens));
290    }
291}
292
293impl<T: Parse, D: Parse> RangedRepeats for DelimitedVec<T, D> {
294    fn parse_repeats(tokens: &mut TokenIter, min: usize, max: usize) -> Result<Self> {
295        let mut output = Vec::with_capacity(min);
296        for _ in 0..max {
297            if let Ok(delimited) = Delimited::<T, D>::parse(tokens) {
298                let done = delimited.delimiter.is_none();
299                output.push(delimited);
300                if done {
301                    break;
302                }
303            } else {
304                break;
305            }
306        }
307
308        if output.len() >= min {
309            Ok(Self(output))
310        } else {
311            Error::other(
312                tokens,
313                format!("less than {} elements, got {}", min, output.len()),
314            )
315        }
316    }
317}
318
319impl<T, D> IntoIterator for DelimitedVec<T, D> {
320    type Item = Delimited<T, D>;
321    type IntoIter = std::vec::IntoIter<Self::Item>;
322
323    fn into_iter(self) -> Self::IntoIter {
324        self.0.into_iter()
325    }
326}
327
328#[mutants::skip]
329impl<T: std::fmt::Debug, D: std::fmt::Debug> std::fmt::Debug for DelimitedVec<T, D> {
330    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
331        f.debug_tuple(&format!(
332            "DelimitedVec<{}, {}>",
333            std::any::type_name::<T>(),
334            std::any::type_name::<D>()
335        ))
336        .field(&self.0)
337        .finish()
338    }
339}
340
341/// Vector of `T` delimited by `,`
342pub type CommaDelimitedVec<T> = DelimitedVec<T, Comma>;
343/// Vector of `T` delimited by `;`
344pub type SemicolonDelimitedVec<T> = DelimitedVec<T, Semicolon>;
345/// Vector of `T` delimited by `::`
346pub type PathSepDelimitedVec<T> = DelimitedVec<T, PathSep>;
347/// Vector of `T` delimited by `.`
348pub type DotDelimitedVec<T> = DelimitedVec<T, Dot>;
349/// Vector of `T` delimited by `:`
350pub type ColonDelimitedVec<T> = DelimitedVec<T, Colon>;
351
352/// Like `DelimitedVec<T,D>` but with a minimum and maximum (inclusive) number of elements.
353/// Parsing will succeed when at least the minimum number of elements is reached and stop at
354/// the maximum number.  The delimiter `D` defaults to [`Nothing`] to parse sequences which
355/// don't have delimiters.
356#[derive(Clone)]
357pub struct Repeats<const MIN: usize, const MAX: usize, T, D = Nothing>(pub Vec<Delimited<T, D>>);
358
359impl<const MIN: usize, const MAX: usize, T: Parse, D: Parse> Parser for Repeats<MIN, MAX, T, D> {
360    fn parser(tokens: &mut TokenIter) -> Result<Self> {
361        let mut output = Vec::new();
362        while let Ok(delimited) = Delimited::<T, D>::parse(tokens) {
363            let done = delimited.delimiter.is_none();
364            output.push(delimited);
365            #[allow(unused_comparisons)]
366            if done || output.len() >= MAX {
367                break;
368            }
369        }
370
371        #[allow(unused_comparisons)]
372        if output.len() >= MIN {
373            Ok(Self(output))
374        } else {
375            Error::other(
376                tokens,
377                format!(
378                    "less than MIN Repeats<MIN={MIN}, MAX={MAX}, {}, {}>, got {} repeats",
379                    std::any::type_name::<T>(),
380                    std::any::type_name::<D>(),
381                    output.len()
382                ),
383            )
384        }
385    }
386}
387
388impl<const MIN: usize, const MAX: usize, T: ToTokens, D: ToTokens> ToTokens
389    for Repeats<MIN, MAX, T, D>
390{
391    fn to_tokens(&self, tokens: &mut TokenStream) {
392        self.0.iter().for_each(|value| value.to_tokens(tokens));
393    }
394}
395
396/// Converts a `[Repeats<MIN, MAX, T, D>`] into a [`Vec<T>`].
397/// As with [`DelimitedVec`] this loses the potentially stateful delimiters.
398impl<const MIN: usize, const MAX: usize, T, D> From<Repeats<MIN, MAX, T, D>> for Vec<T> {
399    fn from(repeats: Repeats<MIN, MAX, T, D>) -> Self {
400        repeats
401            .0
402            .into_iter()
403            .map(|delimited| delimited.value)
404            .collect()
405    }
406}
407
408impl<const MIN: usize, const MAX: usize, T, D> IntoIterator for Repeats<MIN, MAX, T, D> {
409    type Item = Delimited<T, D>;
410    type IntoIter = std::vec::IntoIter<Self::Item>;
411
412    fn into_iter(self) -> Self::IntoIter {
413        self.0.into_iter()
414    }
415}
416
417#[mutants::skip]
418impl<const MIN: usize, const MAX: usize, T: std::fmt::Debug, D: std::fmt::Debug> std::fmt::Debug
419    for Repeats<MIN, MAX, T, D>
420{
421    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
422        f.debug_tuple(&format!(
423            "Repeats<{MIN}, {MAX}, {}, {}>",
424            std::any::type_name::<T>(),
425            std::any::type_name::<D>()
426        ))
427        .field(&self.0)
428        .finish()
429    }
430}
431
432/// Any number of T delimited by D or [`Nothing`]
433pub type Any<T, D = Nothing> = Repeats<0, { usize::MAX }, T, D>;
434/// One or more of T delimited by D or [`Nothing`]
435pub type Many<T, D = Nothing> = Repeats<1, { usize::MAX }, T, D>;
436/// Zero or one of T delimited by D or [`Nothing`]
437pub type Optional<T, D = Nothing> = Repeats<0, 1, T, D>;
438/// Exactly N of T delimited by D or [`Nothing`]
439pub type Exactly<const N: usize, T, D = Nothing> = Repeats<N, N, T, D>;
440/// At most N of T delimited by D or [`Nothing`]
441pub type AtMost<const N: usize, T, D = Nothing> = Repeats<0, N, T, D>;
442/// At least N of T delimited by D or [`Nothing`]
443pub type AtLeast<const N: usize, T, D = Nothing> = Repeats<N, { usize::MAX }, T, D>;
444
445// PLANNED: needs https://github.com/rust-lang/rust/issues/96097 impl<const N: usize, T: Parse> Parser for [T;N] {