1use proc_macro2::TokenTree;
2
3use crate::{Extractor, FromMacro, Iter, Parenthesized, StreamExtract, CommaExtractor, EndOfStream};
4
5#[derive(Debug)]
19pub struct MultiExtractor<T>(pub T);
20
21macro_rules! multi_extract_tuple {
22 () => {};
23 ($this: ident $(,$thing: ident)* $(,)?) => {
24 impl<$this, $($thing),*> Extractor for MultiExtractor<($this, $($thing),*)> where $this: Extractor, $($thing: Extractor),*{
25 fn extract(iter: &mut impl Iterator<Item=proc_macro2::TokenTree>) -> Result<Self, crate::Error> {
26 Ok(Self((
27 $this::extract(iter)?,
28 $($thing::extract(iter)?,)*
29 )))
30 }
31 }
32 multi_extract_tuple!($($thing),*);
33 };
34}
35
36multi_extract_tuple!(A, B, C, D, E, F, G, H, I, J, K, L,);
37
38macro_rules! tuple_impl {
39 () => {};
40 ($first: ident $(,$thing: ident)* $(,)?) => {
41 impl<$first, $($thing),*> FromMacro for ($first, $($thing),*) where $first: FromMacro, $($thing: FromMacro),* {
42 fn from_one(tt: TokenTree) -> Result<Self, crate::Error> {
43 let Parenthesized(Iter(mut iter)) = Parenthesized::from_one(tt)?;
44 let result = (
45 {
46 let CommaExtractor(x) = iter.extract::<CommaExtractor<$first>>()?;
47 x
48 },
49 $({
50 let CommaExtractor(x) = iter.extract::<CommaExtractor<$thing>>()?;
51 x
52 },)*
53 );
54 let EndOfStream = iter.extract()?;
55 Ok(result)
56 }
57 }
58 tuple_impl!($($thing),*);
59 };
60}
61
62tuple_impl!(A, B, C, D, E, F, G, H, I, J, K, L,);