2
2
* License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
4
5
+ #[ macro_use] extern crate procedural_masquarade;
5
6
extern crate phf_codegen;
6
7
extern crate proc_macro;
7
8
#[ macro_use] extern crate quote;
8
9
extern crate syn;
9
10
10
11
use std:: ascii:: AsciiExt ;
11
12
12
- /// Panic if any string contains ASCII uppercase letters.
13
- /// Emit a `MAX_LENGTH` constant with the length of the longest string.
14
- #[ proc_macro_derive( cssparser_internal__assert_ascii_lowercase__max_len) ]
15
- pub fn assert_ascii_lowercase_max_len ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
16
- max_len_common ( input, |token_trees| {
17
- let tokens = quote ! ( match x { #( #token_trees ) * } ) ;
18
- let expr = syn:: parse_expr ( tokens. as_str ( ) ) . unwrap ( ) ;
13
+ define_proc_macros ! {
14
+ /// Panic if any string contains ASCII uppercase letters.
15
+ /// Emit a `MAX_LENGTH` constant with the length of the longest string.
16
+ #[ allow( non_snake_case) ]
17
+ pub fn cssparser_internal__assert_ascii_lowercase__max_len( input: & str ) -> String {
18
+ let expr = syn:: parse_expr( & format!( "match x {{ {} }}" , input) ) . unwrap( ) ;
19
19
let arms = match expr {
20
20
syn:: Expr { node: syn:: ExprKind :: Match ( _, ref arms) , .. } => arms,
21
21
_ => panic!( "expected a match expression, got {:?}" , expr)
22
22
} ;
23
- arms. iter ( ) . flat_map ( |arm| & arm. pats ) . filter_map ( |pattern| {
23
+ max_len ( arms. iter( ) . flat_map( |arm| & arm. pats) . filter_map( |pattern| {
24
24
let expr = match * pattern {
25
25
syn:: Pat :: Lit ( ref expr) => expr,
26
26
syn:: Pat :: Wild |
@@ -42,36 +42,23 @@ pub fn assert_ascii_lowercase_max_len(input: proc_macro::TokenStream) -> proc_ma
42
42
}
43
43
_ => panic!( "expected string pattern, got {:?}" , expr)
44
44
}
45
- } ) . max ( )
46
- } )
47
- }
48
-
49
- /// Emit a `MAX_LENGTH` constant with the length of the longest string.
50
- #[ proc_macro_derive( cssparser_internal__max_len) ]
51
- pub fn max_len ( input : proc_macro:: TokenStream ) -> proc_macro:: TokenStream {
52
- max_len_common ( input, |token_trees| {
53
- token_trees. iter ( ) . map ( |tt| string_literal ( tt) . len ( ) ) . max ( )
54
- } )
55
- }
45
+ } ) )
46
+ }
56
47
57
- fn max_len_common < F > ( input : proc_macro:: TokenStream , f : F ) -> proc_macro:: TokenStream
58
- where F : FnOnce ( & [ syn:: TokenTree ] ) -> Option < usize > {
59
- common ( input, |token_trees| {
60
- let max_length = f ( token_trees) . expect ( "expected at least one string" ) ;
61
- quote ! {
62
- const MAX_LENGTH : usize = #max_length;
63
- }
64
- } )
65
- }
48
+ /// Emit a `MAX_LENGTH` constant with the length of the longest string.
49
+ #[ allow( non_snake_case) ]
50
+ pub fn cssparser_internal__max_len( input: & str ) -> String {
51
+ max_len( syn:: parse_token_trees( input) . unwrap( ) . iter( ) . map( |tt| string_literal( tt) . len( ) ) )
52
+ }
66
53
67
- /// ```
68
- /// static MAP: &'static ::phf::Map<&'static str, $ValueType> = …;
69
- /// ```
70
- ///
71
- /// Map keys are ASCII-lowercased.
72
- # [ proc_macro_derive ( cssparser_internal__phf_map ) ]
73
- pub fn phf_map ( input : proc_macro :: TokenStream ) -> proc_macro :: TokenStream {
74
- common ( input , | token_trees| {
54
+ /// ```
55
+ /// static MAP: &'static ::phf::Map<&'static str, $ValueType> = …;
56
+ /// ```
57
+ ///
58
+ /// Map keys are ASCII-lowercased.
59
+ # [ allow ( non_snake_case ) ]
60
+ pub fn cssparser_internal__phf_map ( input: & str ) -> String {
61
+ let token_trees = syn :: parse_token_trees ( input ) . unwrap ( ) ;
75
62
let value_type = & token_trees[ 0 ] ;
76
63
let pairs: Vec <_> = token_trees[ 1 ..] . chunks( 2 ) . map( |chunk| {
77
64
let key = string_literal( & chunk[ 0 ] ) ;
@@ -91,52 +78,13 @@ pub fn phf_map(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
91
78
map. build( & mut initializer_bytes) . unwrap( ) ;
92
79
tokens. append( :: std:: str :: from_utf8( & initializer_bytes) . unwrap( ) ) ;
93
80
tokens. append( ";" ) ;
94
- tokens
95
- } )
96
- }
97
-
98
- fn common < F > ( input : proc_macro:: TokenStream , f : F ) -> proc_macro:: TokenStream
99
- where F : FnOnce ( & [ syn:: TokenTree ] ) -> quote:: Tokens {
100
- let input = syn:: parse_macro_input ( & input. to_string ( ) ) . unwrap ( ) ;
101
- let token_trees = find_smuggled_tokens ( & input) ;
102
- let tokens = f ( token_trees) ;
103
- tokens. as_str ( ) . parse ( ) . unwrap ( )
81
+ tokens. to_string( )
82
+ }
104
83
}
105
84
106
- /// Return the `…` part in:
107
- ///
108
- /// ```rust
109
- /// enum Somthing {
110
- /// Input = (0, stringify!(…)).0
111
- /// }
112
- /// ```
113
- fn find_smuggled_tokens ( input : & syn:: DeriveInput ) -> & [ syn:: TokenTree ] {
114
- let discriminant = match input. body {
115
- syn:: Body :: Enum ( ref variants) if variants. len ( ) == 1 => & variants[ 0 ] . discriminant ,
116
- _ => panic ! ( "expected single-variant enum, got {:?}" , input. body)
117
- } ;
118
- let tuple = match * discriminant {
119
- Some ( syn:: ConstExpr :: Other ( syn:: Expr { node : syn:: ExprKind :: TupField ( ref t, 0 ) , .. } ) ) => t,
120
- _ => panic ! ( "expected a discriminant like tuple.0, got {:?}" , discriminant)
121
- } ;
122
- let expr = match * * tuple {
123
- syn:: Expr { node : syn:: ExprKind :: Tup ( ref values) , .. } if values. len ( ) == 2 => & values[ 1 ] ,
124
- _ => panic ! ( "expected non-empty tuple, got {:?}" , tuple)
125
- } ;
126
- let macro_args = match * expr {
127
- syn:: Expr { node : syn:: ExprKind :: Mac (
128
- syn:: Mac { ref tts, path : syn:: Path { global : false , ref segments } }
129
- ) , .. }
130
- if segments. len ( ) == 1
131
- && segments[ 0 ] == syn:: PathSegment :: from ( "stringify" )
132
- && tts. len ( ) == 1
133
- => & tts[ 0 ] ,
134
- _ => panic ! ( "expected a stringify!(…) macro, got {:?}" , expr)
135
- } ;
136
- match * macro_args {
137
- syn:: TokenTree :: Delimited ( syn:: Delimited { ref tts, delim : syn:: DelimToken :: Paren } ) => tts,
138
- _ => panic ! ( "expected (…) parentheses, got {:?}" , macro_args)
139
- }
85
+ fn max_len < I : Iterator < Item =usize > > ( lengths : I ) -> String {
86
+ let max_length = lengths. max ( ) . expect ( "expected at least one string" ) ;
87
+ quote ! ( const MAX_LENGTH : usize = #max_length; ) . to_string ( )
140
88
}
141
89
142
90
fn string_literal ( token : & syn:: TokenTree ) -> & str {
0 commit comments