@@ -6,103 +6,72 @@ extern crate proc_macro;
66
77use proc_macro:: TokenStream ;
88
9- /// Input: a `match` expression.
10- ///
11- /// Output: a `MAX_LENGTH` constant with the length of the longest string pattern.
12- ///
13- /// Panic if the arms contain non-string patterns,
14- /// or string patterns that contains ASCII uppercase letters.
9+ /// Implementation detail of the `match_ignore_ascii_case!` macro
1510#[ allow( non_snake_case) ]
1611#[ proc_macro]
17- pub fn cssparser_internal__assert_ascii_lowercase__max_len ( input : TokenStream ) -> TokenStream {
18- let expr: syn:: ExprMatch = syn:: parse_macro_input!( input) ;
19- let strings = expr
20- . arms
21- . iter ( )
22- . flat_map ( |arm| match arm. pat {
23- syn:: Pat :: Or ( ref p) => p. cases . iter ( ) . collect ( ) ,
24- ref p => vec ! [ p] ,
25- } )
26- . filter_map ( |pattern| {
27- let expr = match pattern {
28- syn:: Pat :: Lit ( expr) => expr,
29- syn:: Pat :: Wild ( _) => return None ,
30- _ => panic ! ( "expected string or wildcard pattern, got {:?}" , pattern) ,
31- } ;
32- match * expr. expr {
33- syn:: Expr :: Lit ( syn:: ExprLit {
34- lit : syn:: Lit :: Str ( ref lit) ,
35- ..
36- } ) => {
37- assert_eq ! (
38- lit. value( ) ,
39- lit. value( ) . to_ascii_lowercase( ) ,
40- "string patterns must be given in ASCII lowercase"
41- ) ;
42- Some ( lit)
43- }
44- _ => panic ! ( "expected string pattern, got {:?}" , expr) ,
45- }
46- } ) ;
47- max_len ( strings)
48- }
49-
50- /// Input: string literals with no separator
51- ///
52- /// Output: a `MAX_LENGTH` constant with the length of the longest string.
53- #[ allow( non_snake_case) ]
54- #[ proc_macro]
55- pub fn cssparser_internal__max_len ( input : TokenStream ) -> TokenStream {
56- struct Input ( Vec < syn:: LitStr > ) ;
12+ pub fn cssparser_internal__match_ignore_ascii_case__support ( input : TokenStream ) -> TokenStream {
13+ struct Input {
14+ max_length : usize ,
15+ }
5716
5817 impl syn:: parse:: Parse for Input {
5918 fn parse ( input : syn:: parse:: ParseStream ) -> syn:: parse:: Result < Self > {
60- let mut strings = Vec :: new ( ) ;
19+ let mut max_length = 0 ;
6120 while !input. is_empty ( ) {
62- strings. push ( input. parse ( ) ?)
21+ if input. peek ( syn:: Token ![ _] ) {
22+ input. parse :: < syn:: Token ![ _] > ( ) . unwrap ( ) ;
23+ continue ;
24+ }
25+ let lit: syn:: LitStr = input. parse ( ) ?;
26+ let value = lit. value ( ) ;
27+ if value. to_ascii_lowercase ( ) != value {
28+ return Err ( syn:: Error :: new ( lit. span ( ) , "must be ASCII-lowercase" ) ) ;
29+ }
30+ max_length = max_length. max ( value. len ( ) ) ;
6331 }
64- Ok ( Self ( strings ) )
32+ Ok ( Input { max_length } )
6533 }
6634 }
6735
68- let strings: Input = syn:: parse_macro_input!( input) ;
69- max_len ( strings. 0 . iter ( ) )
70- }
71-
72- fn max_len < ' a , I : Iterator < Item = & ' a syn:: LitStr > > ( strings : I ) -> TokenStream {
73- let max_length = strings
74- . map ( |s| s. value ( ) . len ( ) )
75- . max ( )
76- . expect ( "expected at least one string" ) ;
77- quote:: quote!( pub ( super ) const MAX_LENGTH : usize = #max_length; ) . into ( )
36+ let Input { max_length } = syn:: parse_macro_input!( input) ;
37+ quote:: quote!(
38+ pub ( super ) const MAX_LENGTH : usize = #max_length;
39+ )
40+ . into ( )
7841}
7942
80- /// Input: A type, followed by pairs of string literal keys and expression values. No separator.
81- ///
82- /// Output: a rust-phf map, with keys ASCII-lowercased:
83- /// ```text
84- /// static MAP: &'static ::cssparser::phf::Map<&'static str, $ValueType> = …;
85- /// ```
43+ /// Implementation detail of the `ascii_case_insensitive_phf_map!` macro
8644#[ allow( non_snake_case) ]
8745#[ proc_macro]
88- pub fn cssparser_internal__phf_map ( input : TokenStream ) -> TokenStream {
46+ pub fn cssparser_internal__ascii_case_insensitive_phf_map__support (
47+ input : TokenStream ,
48+ ) -> TokenStream {
8949 struct Input {
9050 value_type : syn:: Type ,
51+ max_key_length : usize ,
9152 keys : Vec < syn:: LitStr > ,
9253 values : Vec < syn:: Expr > ,
9354 }
9455
9556 impl syn:: parse:: Parse for Input {
9657 fn parse ( input : syn:: parse:: ParseStream ) -> syn:: parse:: Result < Self > {
58+ let value_type = input. parse ( ) ?;
59+ let mut max_key_length = 0 ;
9760 let mut keys = Vec :: new ( ) ;
9861 let mut values = Vec :: new ( ) ;
99- let value_type = input. parse ( ) ?;
10062 while !input. is_empty ( ) {
101- keys. push ( input. parse ( ) ?) ;
63+ let key: syn:: LitStr = input. parse ( ) ?;
64+ let key_value = key. value ( ) ;
65+ max_key_length = max_key_length. max ( key_value. len ( ) ) ;
66+ keys. push ( syn:: LitStr :: new (
67+ & key_value. to_ascii_lowercase ( ) ,
68+ key. span ( ) ,
69+ ) ) ;
10270 values. push ( input. parse ( ) ?) ;
10371 }
10472 Ok ( Input {
10573 value_type,
74+ max_key_length,
10675 keys,
10776 values,
10877 } )
@@ -111,14 +80,12 @@ pub fn cssparser_internal__phf_map(input: TokenStream) -> TokenStream {
11180
11281 let Input {
11382 value_type,
83+ max_key_length,
11484 keys,
11585 values,
11686 } = syn:: parse_macro_input!( input) ;
117- let keys = keys
118- . iter ( )
119- . map ( |s| syn:: LitStr :: new ( & s. value ( ) . to_ascii_lowercase ( ) , s. span ( ) ) ) ;
120-
12187 quote:: quote!(
88+ pub ( super ) const MAX_LENGTH : usize = #max_key_length;
12289 pub ( super ) static MAP : Map <& ' static str , #value_type> = phf_map! {
12390 #(
12491 #keys => #values,
0 commit comments