parse_more/
lib.rs

1//! # parse-more
2//! Parse-more is an extension of the [syn::parse::Parse] trait from the [syn](https://docs.rs/syn/) crate, allowing to parse input from procedural macros directly, without having to create a custom structure and implementing the [syn::parse::Parse] trait on it.
3//!
4//! It provides classic [syn](https://docs.rs/syn/) macros and functions variant, using the [ParseMore] trait instead.
5//!
6//! # Example
7//!
8//! ```
9//! # extern crate proc_macro;
10//! use quote::quote;
11//! use parse_more::{parse_more_macro_input, Concat, Braced};
12//! use proc_macro::TokenStream;
13//! use syn::{Expr, Ident, Token, punctuated::Punctuated};
14//!
15//! # const IGNORE_TOKENS: &str = stringify! {
16//! #[proc_macro]
17//! # };
18//! pub fn complex_args(input: TokenStream) -> TokenStream {
19//!    let content = parse_more_macro_input!(
20//!        input as Punctuated<Concat<Ident, Token![=>], Braced<(Ident, Expr)>>, Token![,]>
21//!    );
22//!    content
23//!        .into_iter()
24//!        .map(|concat| {
25//!            // Second item is discarded (it's the => arrow)
26//!            let (ident, _, Braced((other_ident, literal))) = concat.into();
27//!            quote! {
28//!                println!("{}: {} versus other type {}", #literal, (-1i8) as #ident, (-1i8) as #other_ident);
29//!            }
30//!        })
31//!        .collect::<proc_macro2::TokenStream>()
32//!        .into()
33//! }
34//! ```
35//! And then :
36//! ```
37//! # macro_rules! complex_args { ($($tt:tt)*) => {} }
38//! complex_args! {
39//!     u8 => {
40//!         (i8, "u8 integer")
41//!     },
42//!     u16 => {
43//!         (i16, "u16 integer")
44//!     },
45//!     Foo => {
46//!         (Bar, 8 + 42)
47//!     }
48//! }
49//! ```
50
51extern crate proc_macro;
52
53pub mod syn_types;
54
55/// Re-export proc macro.
56pub use parse_more_macros::{filler, parse_more};
57
58use syn::{
59    braced, bracketed, parenthesized,
60    parse::{Nothing, Parse},
61    punctuated::Punctuated,
62    LitInt, LitStr,
63};
64
65/// Parsing interface implemented by all types from the [syn] crate which already implement [syn::parse::Parse], and some others usefull ones.
66/// Use the [parse_more_auto_impl] macros to easily implement [ParseMore] on a type which already implement [syn::parse::Parse].
67pub trait ParseMore: Sized {
68    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self>;
69}
70
71/// This wrapper implements [syn::parse::Parse] when T implements [ParseMore]. It permits to use this wrapper and a type implementing [ParseMore] in a parsing function from [syn].
72///
73/// You should probably use [parse_more()], [parse_more_macro_input], or any other function from this crate instead of using this type directly.
74///
75/// # Example
76///
77/// ```
78/// # extern crate proc_macro;
79/// use quote::quote;
80/// use parse_more::ParseMoreWrapper;
81/// use proc_macro::TokenStream;
82/// use syn::{Ident, Token};
83///
84/// # const IGNORE_TOKENS: &str = stringify! {
85/// #[proc_macro]
86/// # };
87/// pub fn flip_identifiers(input: TokenStream) -> TokenStream {
88///     let (ident_a, arrow, ident_b) = syn::parse::<ParseMoreWrapper<(Ident, Token![=>], Ident)>>(input).unwrap().0;
89///     quote! {
90///         #ident_b <= #ident_a
91///     }.into()
92/// }
93/// ```
94pub struct ParseMoreWrapper<T>(pub T);
95
96/// Call the [ParseMore::parse] method.
97impl<T: ParseMore> Parse for ParseMoreWrapper<T> {
98    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
99        Ok(ParseMoreWrapper(ParseMore::parse(input)?))
100    }
101}
102
103/// This macro auto-implements the [ParseMore] traits on its arguments, which *MUST* implement the [syn::parse::Parse] trait.
104/// It allows using custom types inside of any parse-more macros/functions.
105///
106/// See the [macro@parse_more] macro.
107///
108/// # Example
109///
110/// ```
111/// use parse_more::parse_more_auto_impl;
112/// use syn::{Ident, Token};
113///
114/// struct MyParsedStruct(Ident, Ident);
115///
116/// impl syn::parse::Parse for MyParsedStruct {
117///     fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
118///         let a = input.parse()?;
119///         input.parse::<Token![=>]>()?;
120///         let b = input.parse()?;
121///         Ok(Self(a, b))
122///     }
123/// }
124///
125/// parse_more_auto_impl! {
126///     MyParsedStruct
127/// }
128/// ```
129#[macro_export]
130macro_rules! parse_more_auto_impl {
131    ($($ty:ty),*) => {
132        $(impl $crate::ParseMore for $ty {
133            fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
134                <Self as syn::parse::Parse>::parse(input)
135            }
136        })*
137    }
138}
139
140/// Implement [ParseMore] for a given tuple.
141macro_rules! tuple_impls {
142    ($first:ident) => {
143        impl<$first:ParseMore> ParseMore for ($first, ) {
144            fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
145                let content;
146                parenthesized!(content in input);
147                let first = content.parse::<ParseMoreWrapper<$first>>()?.0;
148                content.parse::<syn::Token![,]>()?;
149                Ok((first,))
150            }
151        }
152    };
153    ($first:ident $($generics:ident)*) => {
154        impl<$first:ParseMore, $($generics: ParseMore),*> ParseMore for ($first, $($generics,)*) {
155            fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
156                let content;
157                parenthesized!(content in input);
158                let first = content.parse::<ParseMoreWrapper<$first>>()?.0;
159                let res = Ok((first,
160                    $({
161                        content.parse::<syn::Token![,]>()?;
162                        content.parse::<ParseMoreWrapper<$generics>>()?.0
163                    },)*
164                ));
165
166                // If there is a remaining comma, parse it
167                if content.peek(syn::Token![,]) {
168                    content.parse::<syn::Token![,]>().unwrap();
169                }
170                res
171            }
172        }
173    };
174}
175
176/// Inner code of the [for_each_tuple] macro.
177macro_rules! for_each_tuple_ {
178    ($mac:ident =>) => {};
179    ($mac:ident => $first:ident, $($generics:ident,)*) => {
180        $mac! {
181            $first $($generics)*
182        }
183        for_each_tuple_ ! {
184            $mac => $($generics,)*
185        }
186    };
187}
188
189/// Call a macro over every tuple size between 1 and 20.
190macro_rules! for_each_tuple {
191    ($mac:ident) => {
192        for_each_tuple_! {
193            $mac => A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T,
194        }
195    };
196}
197
198// Generate [ParseMore] impls for tuples.
199for_each_tuple! {
200    tuple_impls
201}
202
203/// Implement [ParseMore] for the array type.
204/// ```
205/// # extern crate proc_macro;
206/// use quote::quote;
207/// use parse_more::parse_more_macro_input;
208/// use proc_macro::TokenStream;
209/// use syn::{Ident, Token};
210///
211/// # const IGNORE_TOKENS: &str = stringify! {
212/// #[proc_macro]
213/// # };
214/// pub fn identifiers_sum(input: TokenStream) -> TokenStream {
215///     let idents = parse_more_macro_input!(input as [Ident; 3]);
216///     let [a, b, c] = idents;
217///     quote! {
218///         #a + #b + #c
219///     }.into()
220/// }
221/// ```
222impl<T: ParseMore, const N: usize> ParseMore for [T; N] {
223    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
224        let content;
225        bracketed!(content in input);
226
227        let mut res = vec![];
228        for i in 0..N {
229            if i != 0 {
230                content.parse::<syn::Token![,]>()?;
231            }
232            res.push(content.parse::<ParseMoreWrapper<T>>()?.0)
233        }
234
235        // If there is a remaining comma, parse it
236        if content.peek(syn::Token![,]) {
237            content.parse::<syn::Token![,]>().unwrap();
238        }
239        Ok(unsafe { res.try_into().unwrap_unchecked() })
240    }
241}
242
243/// Implement [ParseMore] for the [Vec] type, with a behaviour similar to [syn::punctuated::Punctuated<T, syn::parse::Nothing>]
244/// ```
245/// # extern crate proc_macro;
246/// use quote::quote;
247/// use parse_more::parse_more_macro_input;
248/// use proc_macro::TokenStream;
249/// use syn::Ident;
250///
251/// # const IGNORE_TOKENS: &str = stringify! {
252/// #[proc_macro]
253/// # };
254/// pub fn identifiers_sum(input: TokenStream) -> TokenStream {
255///     let idents = parse_more_macro_input!(input as Vec<Ident>);
256///     idents.into_iter().map(|ident| quote! {
257///         #ident
258///     }).collect::<proc_macro2::TokenStream>().into()
259/// }
260/// ```
261impl<T: ParseMore> ParseMore for Vec<T> {
262    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
263        let mut res = vec![];
264        while let Ok(parsed) = input.parse::<ParseMoreWrapper<T>>() {
265            res.push(parsed.0);
266        }
267        Ok(res)
268    }
269}
270
271/// Implement [ParseMore] for the [syn::punctuated::Punctuated] type.
272/// ```
273/// # extern crate proc_macro;
274/// use quote::quote;
275/// use parse_more::parse_more_macro_input;
276/// use proc_macro::TokenStream;
277/// use syn::{Ident, Token, punctuated::Punctuated};
278///
279/// # const IGNORE_TOKENS: &str = stringify! {
280/// #[proc_macro]
281/// # };
282/// pub fn identifiers_sum(input: TokenStream) -> TokenStream {
283///     let idents = parse_more_macro_input!(input as Punctuated<Ident, Token![,]>);
284///     idents.into_iter().map(|ident| quote! {
285///         #ident
286///     }).collect::<proc_macro2::TokenStream>().into()
287/// }
288/// ```
289impl<T: ParseMore, P: ParseMore> ParseMore for Punctuated<T, P> {
290    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
291        let mut res = Punctuated::new();
292        let wrapped =
293            Punctuated::<ParseMoreWrapper<T>, ParseMoreWrapper<P>>::parse_terminated(input)?;
294
295        // Unwrap parsed values
296        wrapped.into_pairs().for_each(|pair| {
297            let pair = pair.into_tuple();
298            res.push_value(pair.0 .0);
299            if let Some(punct) = pair.1 {
300                res.push_punct(punct.0);
301            }
302        });
303
304        Ok(res)
305    }
306}
307
308/// Parse successive items.
309#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
310pub struct Concat<A, B, C = Nothing, D = Nothing, E = Nothing, F = Nothing, G = Nothing> {
311    first: A,
312    second: B,
313    third: C,
314    fourth: D,
315    fifth: E,
316    sixth: F,
317    seventh: G,
318}
319
320impl<A, B, C, D, E, F, G> From<Concat<A, B, C, D, E, F, G>> for (A, B, C, D, E, F, G) {
321    fn from(value: Concat<A, B, C, D, E, F, G>) -> Self {
322        (
323            value.first,
324            value.second,
325            value.third,
326            value.fourth,
327            value.fifth,
328            value.sixth,
329            value.seventh,
330        )
331    }
332}
333impl<A, B, C, D, E, F> From<Concat<A, B, C, D, E, F>> for (A, B, C, D, E, F) {
334    fn from(value: Concat<A, B, C, D, E, F>) -> Self {
335        (
336            value.first,
337            value.second,
338            value.third,
339            value.fourth,
340            value.fifth,
341            value.sixth,
342        )
343    }
344}
345impl<A, B, C, D, E> From<Concat<A, B, C, D, E>> for (A, B, C, D, E) {
346    fn from(value: Concat<A, B, C, D, E>) -> Self {
347        (
348            value.first,
349            value.second,
350            value.third,
351            value.fourth,
352            value.fifth,
353        )
354    }
355}
356impl<A, B, C, D> From<Concat<A, B, C, D>> for (A, B, C, D) {
357    fn from(value: Concat<A, B, C, D>) -> Self {
358        (value.first, value.second, value.third, value.fourth)
359    }
360}
361impl<A, B, C> From<Concat<A, B, C>> for (A, B, C) {
362    fn from(value: Concat<A, B, C>) -> Self {
363        (value.first, value.second, value.third)
364    }
365}
366impl<A, B> From<Concat<A, B>> for (A, B) {
367    fn from(value: Concat<A, B>) -> Self {
368        (value.first, value.second)
369    }
370}
371impl<A, B> Concat<A, B> {
372    /// Convert itself to a tuple containing the parsed values.
373    pub fn into_tuple2(self) -> (A, B) {
374        self.into()
375    }
376}
377impl<A, B, C> Concat<A, B, C> {
378    /// Convert itself to a tuple containing the parsed values.
379    pub fn into_tuple3(self) -> (A, B, C) {
380        self.into()
381    }
382}
383impl<A, B, C, D> Concat<A, B, C, D> {
384    /// Convert itself to a tuple containing the parsed values.
385    pub fn into_tuple4(self) -> (A, B, C, D) {
386        self.into()
387    }
388}
389impl<A, B, C, D, E> Concat<A, B, C, D, E> {
390    /// Convert itself to a tuple containing the parsed values.
391    pub fn into_tuple5(self) -> (A, B, C, D, E) {
392        self.into()
393    }
394}
395impl<A, B, C, D, E, F> Concat<A, B, C, D, E, F> {
396    /// Convert itself to a tuple containing the parsed values.
397    pub fn into_tuple6(self) -> (A, B, C, D, E, F) {
398        self.into()
399    }
400}
401impl<A, B, C, D, E, F, G> Concat<A, B, C, D, E, F, G> {
402    /// Convert itself to a tuple containing the parsed values.
403    pub fn into_tuple7(self) -> (A, B, C, D, E, F, G) {
404        self.into()
405    }
406}
407
408/// Imlement [ParseMore] for the [Concat] type.
409impl<
410        A: ParseMore,
411        B: ParseMore,
412        C: ParseMore,
413        D: ParseMore,
414        E: ParseMore,
415        F: ParseMore,
416        G: ParseMore,
417    > ParseMore for Concat<A, B, C, D, E, F, G>
418{
419    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
420        Ok(Self {
421            first: input.parse::<ParseMoreWrapper<_>>()?.0,
422            second: input.parse::<ParseMoreWrapper<_>>()?.0,
423            third: input.parse::<ParseMoreWrapper<_>>()?.0,
424            fourth: input.parse::<ParseMoreWrapper<_>>()?.0,
425            fifth: input.parse::<ParseMoreWrapper<_>>()?.0,
426            sixth: input.parse::<ParseMoreWrapper<_>>()?.0,
427            seventh: input.parse::<ParseMoreWrapper<_>>()?.0,
428        })
429    }
430}
431
432/// Parse an item surrounded by braces.
433#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
434pub struct Braced<T>(pub T);
435
436/// Imlement [ParseMore] for the [Braced] type.
437impl<T: ParseMore> ParseMore for Braced<T> {
438    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
439        let content;
440        braced!(content in input);
441        Ok(Self(content.parse::<ParseMoreWrapper<T>>()?.0))
442    }
443}
444
445impl<T> Braced<T> {
446    /// Get the parsed value.
447    pub fn value(self) -> T {
448        self.0
449    }
450}
451
452/// Parse an item surrounded by parenthesis.
453#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
454pub struct Parenthesized<T>(pub T);
455
456/// Imlement [ParseMore] for the [Parenthesized] type.
457impl<T: ParseMore> ParseMore for Parenthesized<T> {
458    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
459        let content;
460        parenthesized!(content in input);
461        Ok(Self(content.parse::<ParseMoreWrapper<T>>()?.0))
462    }
463}
464
465impl<T> Parenthesized<T> {
466    /// Get the parsed value.
467    pub fn value(self) -> T {
468        self.0
469    }
470}
471
472/// Parse an item surrounded by brackets.
473#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
474pub struct Bracketed<T>(pub T);
475
476/// Imlement [ParseMore] for the [Bracketed] type.
477impl<T: ParseMore> ParseMore for Bracketed<T> {
478    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
479        let content;
480        bracketed!(content in input);
481        Ok(Self(content.parse::<ParseMoreWrapper<T>>()?.0))
482    }
483}
484
485impl<T> Bracketed<T> {
486    /// Get the parsed value.
487    pub fn value(self) -> T {
488        self.0
489    }
490}
491
492/// Imlement [ParseMore] for the [Option] type.
493impl<T: ParseMore> ParseMore for Option<T> {
494    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
495        // Fork the input to be sure to don't advance the cursor if the parsing fails.
496        let input_forked = input.fork();
497        if let Ok(parsed) = input_forked.parse::<ParseMoreWrapper<T>>() {
498            // Parse it on the primary stream too to advance the cursor
499            // It should not fails.
500            assert!(input.parse::<ParseMoreWrapper<T>>().is_ok());
501            Ok(Some(parsed.0))
502        } else {
503            Ok(None)
504        }
505    }
506}
507
508/// Parse an item surrounded by brackets.
509#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
510pub struct Invalid;
511
512/// Imlement [ParseMore] for the [Invalid] type.
513impl ParseMore for Invalid {
514    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
515        Err(syn::Error::new(input.span(), "Invalid can never be parsed"))
516    }
517}
518
519/// Parse an item in a given list. If multiple types can be parsed, the first one is chosen.
520#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
521pub enum Either<A, B, C = Invalid, D = Invalid, E = Invalid, F = Invalid, G = Invalid> {
522    First(A),
523    Second(B),
524    Third(C),
525    Fourth(D),
526    Fifth(E),
527    Sixth(F),
528    Seventh(G),
529}
530
531impl<A, B, C, D, E, F, G> Either<A, B, C, D, E, F, G> {
532    /// Check if the type of the parsed value is the first one.
533    pub fn is_first(&self) -> bool {
534        matches!(self, Either::First(_))
535    }
536    /// Check if the type of the parsed value is the second one.
537    pub fn is_second(&self) -> bool {
538        matches!(self, Either::Second(_))
539    }
540    /// Check if the type of the parsed value is the third one.
541    pub fn is_third(&self) -> bool {
542        matches!(self, Either::Third(_))
543    }
544    /// Check if the type of the parsed value is the fourth one.
545    pub fn is_fourth(&self) -> bool {
546        matches!(self, Either::Fourth(_))
547    }
548    /// Check if the type of the parsed value is the fifth one.
549    pub fn is_fifth(&self) -> bool {
550        matches!(self, Either::Fifth(_))
551    }
552    /// Check if the type of the parsed value is the sixth one.
553    pub fn is_sixth(&self) -> bool {
554        matches!(self, Either::Sixth(_))
555    }
556    /// Check if the type of the parsed value is the seveth one.
557    pub fn is_seventh(&self) -> bool {
558        matches!(self, Either::Seventh(_))
559    }
560}
561
562/// Imlement [ParseMore] for the [Either] type.
563impl<
564        A: ParseMore,
565        B: ParseMore,
566        C: ParseMore,
567        D: ParseMore,
568        E: ParseMore,
569        F: ParseMore,
570        G: ParseMore,
571    > ParseMore for Either<A, B, C, D, E, F, G>
572{
573    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
574        let mut err;
575        match input.fork().parse::<ParseMoreWrapper<A>>() {
576            Ok(_) => return Ok(Self::First(input.parse::<ParseMoreWrapper<A>>().unwrap().0)),
577            Err(e) => err = e,
578        }
579        match input.fork().parse::<ParseMoreWrapper<B>>() {
580            Ok(_) => {
581                return Ok(Self::Second(
582                    input.parse::<ParseMoreWrapper<B>>().unwrap().0,
583                ))
584            }
585            Err(e) => err.combine(e),
586        }
587        match input.fork().parse::<ParseMoreWrapper<C>>() {
588            Ok(_) => return Ok(Self::Third(input.parse::<ParseMoreWrapper<C>>().unwrap().0)),
589            Err(e) => err.combine(e),
590        }
591        match input.fork().parse::<ParseMoreWrapper<D>>() {
592            Ok(_) => {
593                return Ok(Self::Fourth(
594                    input.parse::<ParseMoreWrapper<D>>().unwrap().0,
595                ))
596            }
597            Err(e) => err.combine(e),
598        }
599        match input.fork().parse::<ParseMoreWrapper<E>>() {
600            Ok(_) => return Ok(Self::Fifth(input.parse::<ParseMoreWrapper<E>>().unwrap().0)),
601            Err(e) => err.combine(e),
602        }
603        match input.fork().parse::<ParseMoreWrapper<F>>() {
604            Ok(_) => return Ok(Self::Sixth(input.parse::<ParseMoreWrapper<F>>().unwrap().0)),
605            Err(e) => err.combine(e),
606        }
607        match input.fork().parse::<ParseMoreWrapper<G>>() {
608            Ok(_) => {
609                return Ok(Self::Seventh(
610                    input.parse::<ParseMoreWrapper<G>>().unwrap().0,
611                ))
612            }
613            Err(e) => err.combine(e),
614        }
615        Err(err)
616    }
617}
618
619macro_rules! integer_impls {
620    ($($ty:ty),*) => {
621        $(
622            /// Imlement [ParseMore] for the [u8] type.
623            impl ParseMore for $ty {
624                fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
625                    input.parse::<LitInt>()?.base10_parse::<Self>()
626                }
627            }
628        )*
629    };
630}
631
632integer_impls! {
633    u8, u16, u32, u64, u128, usize,
634    i8, i16, i32, i64, i128, isize
635}
636
637/// Imlement [ParseMore] for the [String] type.
638impl ParseMore for String {
639    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
640        Ok(input.parse::<LitStr>()?.value())
641    }
642}
643
644/// Same as the [syn::parse_quote] macro, but using the [ParseMore] trait.
645#[macro_export]
646macro_rules! parse_more_quote {
647    ($($tt:tt)*) => {{
648        // Add an type hint for the compiler
649        let __tmp: $crate::ParseMoreWrapper<_> = syn::parse_quote!($($tt:tt)*);
650        __tmp.0
651    }};
652}
653
654/// Same as the [syn::parse_macro_input] macro, but using the [ParseMore] trait.
655#[macro_export]
656macro_rules! parse_more_macro_input {
657    ($tokenstream:ident as $ty:ty) => {
658        match $crate::parse_more::<$ty>($tokenstream) {
659            Ok(data) => data,
660            Err(err) => {
661                return proc_macro::TokenStream::from(err.to_compile_error());
662            }
663        }
664    };
665    ($tokenstream:ident) => {
666        $crate::parse_more_macro_input!($tokenstream as _)
667    };
668}
669
670/// Same as the [syn::parse()] function, but using the [ParseMore] trait.
671pub fn parse_more<T: ParseMore>(tokens: proc_macro::TokenStream) -> syn::Result<T> {
672    Ok(syn::parse::<ParseMoreWrapper<T>>(tokens)?.0)
673}
674
675/// Same as the [syn::parse2] function, but using the [ParseMore] trait.
676pub fn parse2_more<T: ParseMore>(tokens: proc_macro2::TokenStream) -> syn::Result<T> {
677    Ok(syn::parse2::<ParseMoreWrapper<T>>(tokens)?.0)
678}
679
680/// Same as the [syn::parse_str] function, but using the [ParseMore] trait.
681pub fn parse_more_str<T: ParseMore>(s: &str) -> syn::Result<T> {
682    Ok(syn::parse_str::<ParseMoreWrapper<T>>(s)?.0)
683}