@@ -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
@@ -88,7 +90,7 @@ macro_rules! match_ignore_ascii_case {
8890/// # fn main() {} // Make doctest not wrap everything in its own main
8991///
9092/// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
91- /// cssparser::ascii_case_insensitive_phf_map ! {
93+ /// cssparser::ascii_case_insensitive_map ! {
9294/// keywords -> (u8, u8, u8) = {
9395/// "red" => (255, 0, 0),
9496/// "green" => (0, 255, 0),
@@ -100,6 +102,71 @@ 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_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+ /// 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 ) ,+ } ) => {
@@ -126,7 +193,7 @@ macro_rules! ascii_case_insensitive_phf_map {
126193 maxlen
127194 } ;
128195
129- static MAP : phf:: Map <& ' static str , $ValueType> = phf:: phf_map! {
196+ static __MAP : phf:: Map <& ' static str , $ValueType> = phf:: phf_map! {
130197 $(
131198 $key => $value,
132199 ) *
@@ -142,12 +209,12 @@ macro_rules! ascii_case_insensitive_phf_map {
142209 impl $name {
143210 #[ allow( dead_code) ]
144211 fn entries( ) -> impl Iterator <Item = ( & ' static & ' static str , & ' static $ValueType) > {
145- MAP . entries( )
212+ __MAP . entries( )
146213 }
147214
148215 fn get( input: & str ) -> Option <& ' static $ValueType> {
149216 $crate:: _cssparser_internal_to_lowercase!( input, MAX_LENGTH => lowercase) ;
150- MAP . get( lowercase?)
217+ __MAP . get( lowercase?)
151218 }
152219 }
153220 }
0 commit comments