syn_prelude/
parse_terminate_until.rs1use syn::{
2 parse::{Parse, ParseStream, Peek},
3 punctuated::Punctuated,
4};
5
6pub trait ParseTerminatedUntil {
7 fn parse_terminated_until<T, P>(
8 &self,
9 parser: fn(ParseStream) -> syn::Result<T>,
10 separator: P,
11 ) -> syn::Result<Punctuated<T, P::Token>>
12 where
13 P: Peek,
14 P::Token: Parse;
15}
16
17impl ParseTerminatedUntil for ParseStream<'_> {
18 fn parse_terminated_until<T, P>(
19 &self,
20 parser: fn(ParseStream) -> syn::Result<T>,
21 separator: P,
22 ) -> syn::Result<Punctuated<T, P::Token>>
23 where
24 P: Peek,
25 P::Token: Parse,
26 {
27 let _ = separator;
28 let mut punctuated = Punctuated::new();
29
30 loop {
31 if self.is_empty() {
32 break;
33 }
34 punctuated.push_value(parser(self)?);
35 if self.is_empty() {
36 break;
37 }
38 if self.peek(separator) {
39 punctuated.push_punct(self.parse()?);
40 } else {
41 break;
42 }
43 }
44
45 Ok(punctuated)
46 }
47}