1use syn::{
2 parenthesized,
3 parse::{Parse, ParseStream, Result},
4};
5
6struct Parenthesized<V: Parse>(V);
7impl<V: Parse> Parse for Parenthesized<V> {
8 fn parse(stream: ParseStream) -> Result<Self> {
9 let content;
10 let _ = parenthesized!(content in stream);
11 Ok(Self(V::parse(&content)?))
12 }
13}
14macro_rules! make_seperated_func {
15 ($name:ident, $token:path, $type:ident) => {
16 #[inline]
17 pub fn $name<P: Parse>(stream: paste! {[<$type Stream>]}) -> Result<Punctuated<P, $token>> {
18 separated::<P, $token>(stream)
19 }
20 };
21}
22
23pub mod token_stream {
25 use super::Parenthesized;
26 use proc_macro2::TokenStream;
27 use syn::{
28 parse::{Parse, Parser, Result},
29 punctuated::Punctuated,
30 token::Token,
31 };
32
33 #[inline]
34 pub fn parenthesized<V: Parse>(stream: TokenStream) -> Result<V> {
35 syn::parse2::<Parenthesized<V>>(stream).map(|v| v.0)
36 }
37
38 #[inline]
39 pub fn separated<P, T>(stream: TokenStream) -> Result<Punctuated<P, T>>
40 where
41 P: Parse,
42 T: Parse + Token,
43 {
44 Parser::parse2(Punctuated::<P, T>::parse_separated_nonempty, stream)
45 }
46
47 make_seperated_func! {
48 comma_separated, ::syn::token::Comma, Token
49 }
50}
51
52pub mod parse_stream {
54 use super::Parenthesized;
55 use syn::{
56 parse::{Parse, ParseStream, Result},
57 punctuated::Punctuated,
58 };
59
60 #[inline]
61 pub fn parenthesized<V: Parse>(stream: ParseStream) -> Result<V> {
62 stream.parse::<Parenthesized<V>>().map(|v| v.0)
63 }
64
65 #[inline]
66 pub fn separated<P: Parse, T: Parse>(stream: ParseStream) -> Result<Punctuated<P, T>> {
67 <Punctuated<P, T>>::parse_terminated(stream)
68 }
69
70 make_seperated_func! {
71 comma_separated, ::syn::token::Comma, Parse
72 }
73}