3
3
use proc_macro:: { Delimiter , Group , Ident , Punct , Spacing , Span , TokenStream , TokenTree } ;
4
4
5
5
pub ( crate ) fn pin_project ( args : TokenStream , input : TokenStream ) -> TokenStream {
6
- let mut toks = input. into_iter ( ) . collect :: < Vec < _ > > ( ) ;
7
- let last = toks. pop ( ) ;
6
+ let mut impl_generics = vec ! [ ] ;
7
+ let mut ty_generics = vec ! [ ] ;
8
+ let mut rest = vec ! [ ] ;
9
+ let mut nesting = 0 ;
10
+ let mut invalid = false ;
11
+ let mut toks = input. into_iter ( ) ;
12
+ let mut at_start = true ;
13
+ for tt in & mut toks {
14
+ match tt. clone ( ) {
15
+ TokenTree :: Punct ( p) if p. as_char ( ) == '<' => {
16
+ if nesting >= 1 {
17
+ impl_generics. push ( tt) ;
18
+ }
19
+ nesting += 1 ;
20
+ }
21
+ TokenTree :: Punct ( p) if p. as_char ( ) == '>' => {
22
+ if nesting == 0 {
23
+ break ;
24
+ } else {
25
+ nesting -= 1 ;
26
+ if nesting >= 1 {
27
+ impl_generics. push ( tt) ;
28
+ }
29
+ if nesting == 0 {
30
+ break ;
31
+ }
32
+ }
33
+ }
34
+ tt => {
35
+ if nesting == 1 {
36
+ match & tt {
37
+ TokenTree :: Ident ( i) if i. to_string ( ) == "const" => { }
38
+ TokenTree :: Ident ( i) if at_start => {
39
+ ty_generics. push ( tt. clone ( ) ) ;
40
+ ty_generics. push ( TokenTree :: Punct ( Punct :: new ( ',' , Spacing :: Alone ) ) ) ;
41
+ at_start = false ;
42
+ }
43
+ TokenTree :: Punct ( p) if p. as_char ( ) == ',' => at_start = true ,
44
+ TokenTree :: Punct ( p) if p. as_char ( ) == '\'' && at_start => {
45
+ ty_generics. push ( tt. clone ( ) ) ;
46
+ ty_generics. push ( TokenTree :: Punct ( Punct :: new ( ',' , Spacing :: Alone ) ) ) ;
47
+ }
48
+ _ => { }
49
+ }
50
+ }
51
+ if nesting >= 1 {
52
+ impl_generics. push ( tt) ;
53
+ } else if nesting == 0 {
54
+ rest. push ( tt) ;
55
+ }
56
+ }
57
+ }
58
+ }
59
+ rest. extend ( toks) ;
60
+ let last = rest. pop ( ) ;
8
61
TokenStream :: from_iter ( vec ! [
9
62
TokenTree :: Punct ( Punct :: new( ':' , Spacing :: Joint ) ) ,
10
63
TokenTree :: Punct ( Punct :: new( ':' , Spacing :: Alone ) ) ,
@@ -20,13 +73,30 @@ pub(crate) fn pin_project(args: TokenStream, input: TokenStream) -> TokenStream
20
73
TokenTree :: Punct ( Punct :: new( ':' , Spacing :: Alone ) ) ,
21
74
TokenTree :: Punct ( Punct :: new( '@' , Spacing :: Alone ) ) ,
22
75
TokenTree :: Ident ( Ident :: new( "args" , Span :: call_site( ) ) ) ,
23
- TokenTree :: Group ( Group :: new( Delimiter :: Parenthesis , args) ) ,
76
+ TokenTree :: Group ( Group :: new(
77
+ Delimiter :: Parenthesis ,
78
+ TokenStream :: from_iter( args) ,
79
+ ) ) ,
24
80
TokenTree :: Punct ( Punct :: new( ',' , Spacing :: Alone ) ) ,
25
81
TokenTree :: Punct ( Punct :: new( '@' , Spacing :: Alone ) ) ,
26
82
TokenTree :: Ident ( Ident :: new( "sig" , Span :: call_site( ) ) ) ,
27
83
TokenTree :: Group ( Group :: new(
28
84
Delimiter :: Parenthesis ,
29
- TokenStream :: from_iter( toks) ,
85
+ TokenStream :: from_iter( rest) ,
86
+ ) ) ,
87
+ TokenTree :: Punct ( Punct :: new( ',' , Spacing :: Alone ) ) ,
88
+ TokenTree :: Punct ( Punct :: new( '@' , Spacing :: Alone ) ) ,
89
+ TokenTree :: Ident ( Ident :: new( "impl_generics" , Span :: call_site( ) ) ) ,
90
+ TokenTree :: Group ( Group :: new(
91
+ Delimiter :: Parenthesis ,
92
+ TokenStream :: from_iter( impl_generics) ,
93
+ ) ) ,
94
+ TokenTree :: Punct ( Punct :: new( ',' , Spacing :: Alone ) ) ,
95
+ TokenTree :: Punct ( Punct :: new( '@' , Spacing :: Alone ) ) ,
96
+ TokenTree :: Ident ( Ident :: new( "ty_generics" , Span :: call_site( ) ) ) ,
97
+ TokenTree :: Group ( Group :: new(
98
+ Delimiter :: Parenthesis ,
99
+ TokenStream :: from_iter( ty_generics) ,
30
100
) ) ,
31
101
TokenTree :: Punct ( Punct :: new( ',' , Spacing :: Alone ) ) ,
32
102
TokenTree :: Punct ( Punct :: new( '@' , Spacing :: Alone ) ) ,
@@ -35,6 +105,7 @@ pub(crate) fn pin_project(args: TokenStream, input: TokenStream) -> TokenStream
35
105
Delimiter :: Parenthesis ,
36
106
TokenStream :: from_iter( last) ,
37
107
) ) ,
108
+ TokenTree :: Punct ( Punct :: new( ',' , Spacing :: Alone ) ) ,
38
109
] ) ,
39
110
) ) ,
40
111
] )
0 commit comments