@@ -75,6 +75,8 @@ macro_rules! match_ignore_ascii_case {
7575 } ;
7676}
7777
78+ #[ cfg( not( feature = "fast_match_color" ) ) ]
79+ #[ macro_export]
7880/// Define a function `$name(&str) -> Option<&'static $ValueType>`
7981///
8082/// The function finds a match for the input string
@@ -100,13 +102,77 @@ macro_rules! match_ignore_ascii_case {
100102/// ```
101103///
102104/// You can also iterate over the map entries by using `keywords::entries()`.
105+ macro_rules! ascii_case_insensitive_map {
106+ ( $name: ident -> $ValueType: ty = { $( $key: tt => $value: expr ) ,+ } ) => {
107+ ascii_case_insensitive_phf_map!( $name -> $ValueType = { $( $key => $value, ) + } )
108+ } ;
109+ ( $name: ident -> $ValueType: ty = { $( $key: tt => $value: expr, ) + } ) => {
110+
111+ // While the obvious choice for this would be an inner module, it's not possible to
112+ // reference from types from there, see:
113+ // <https://github.com/rust-lang/rust/issues/114369>
114+ //
115+ // So we abuse a struct with static associated functions instead.
116+ #[ allow( non_camel_case_types) ]
117+ struct $name;
118+ impl $name {
119+ #[ allow( dead_code) ]
120+ fn entries( ) -> impl Iterator <Item = ( & ' static & ' static str , & ' static $ValueType) > {
121+ [ $( ( & $key, & $value) , ) * ] . iter( ) . copied( )
122+ }
123+
124+ fn get( input: & str ) -> Option <& ' static $ValueType> {
125+ $crate:: match_ignore_ascii_case!( input,
126+ $( $key => Some ( & $value) , ) *
127+ _ => None ,
128+ )
129+ }
130+ }
131+ }
132+ }
133+
134+ #[ cfg( feature = "fast_match_color" ) ]
135+ #[ macro_export]
136+ /// Define a function `$name(&str) -> Option<&'static $ValueType>`
137+ ///
138+ /// The function finds a match for the input string
139+ /// in a [`phf` map](https://github.com/sfackler/rust-phf)
140+ /// and returns a reference to the corresponding value.
141+ /// Matching is case-insensitive in the ASCII range.
142+ ///
143+ /// ## Example:
144+ ///
145+ /// ```rust
146+ /// # fn main() {} // Make doctest not wrap everything in its own main
147+ ///
148+ /// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
149+ /// cssparser::ascii_case_insensitive_map! {
150+ /// static KEYWORDS : (u8, u8, u8) = {
151+ /// "red" => (255, 0, 0),
152+ /// "green" => (0, 255, 0),
153+ /// "blue" => (0, 0, 255),
154+ /// }
155+ /// }
156+ /// KEYWORDS::get(input).cloned()
157+ /// }
158+ /// ```
159+ ///
160+ /// You can also iterate over the map entries by using `keywords::entries()`.
161+ macro_rules! ascii_case_insensitive_map {
162+ ( $( $any: tt) +) => {
163+ $crate:: ascii_case_insensitive_phf_map!( $( $any) +) ;
164+ } ;
165+ }
166+
167+ /// Fast implementation of `ascii_case_insensitive_map!` using a phf map.
168+ /// See `ascii_case_insensitive_map!` above for docs
169+ #[ cfg( feature = "fast_match_color" ) ]
103170#[ macro_export]
104171macro_rules! ascii_case_insensitive_phf_map {
105172 ( $name: ident -> $ValueType: ty = { $( $key: tt => $value: expr ) ,+ } ) => {
106173 ascii_case_insensitive_phf_map!( $name -> $ValueType = { $( $key => $value, ) + } )
107174 } ;
108175 ( $name: ident -> $ValueType: ty = { $( $key: tt => $value: expr, ) + } ) => {
109- use $crate:: _cssparser_internal_phf as phf;
110176
111177 #[ inline( always) ]
112178 const fn const_usize_max( a: usize , b: usize ) -> usize {
@@ -126,7 +192,7 @@ macro_rules! ascii_case_insensitive_phf_map {
126192 maxlen
127193 } ;
128194
129- static MAP : phf:: Map <& ' static str , $ValueType> = phf:: phf_map! {
195+ static __MAP : :: phf:: Map <& ' static str , $ValueType> = :: phf:: phf_map! {
130196 $(
131197 $key => $value,
132198 ) *
@@ -142,12 +208,12 @@ macro_rules! ascii_case_insensitive_phf_map {
142208 impl $name {
143209 #[ allow( dead_code) ]
144210 fn entries( ) -> impl Iterator <Item = ( & ' static & ' static str , & ' static $ValueType) > {
145- MAP . entries( )
211+ __MAP . entries( )
146212 }
147213
148214 fn get( input: & str ) -> Option <& ' static $ValueType> {
149215 $crate:: _cssparser_internal_to_lowercase!( input, MAX_LENGTH => lowercase) ;
150- MAP . get( lowercase?)
216+ __MAP . get( lowercase?)
151217 }
152218 }
153219 }
0 commit comments