@@ -73,6 +73,8 @@ macro_rules! match_ignore_ascii_case {
7373 } ;
7474}
7575
76+ #[ cfg( not( feature = "fast_match_color" ) ) ]
77+ #[ macro_export]
7678/// Define a function `$name(&str) -> Option<&'static $ValueType>`
7779///
7880/// The function finds a match for the input string
@@ -86,7 +88,7 @@ macro_rules! match_ignore_ascii_case {
8688/// # fn main() {} // Make doctest not wrap everything in its own main
8789///
8890/// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
89- /// cssparser::ascii_case_insensitive_phf_map ! {
91+ /// cssparser::ascii_case_insensitive_map ! {
9092/// static KEYWORDS : (u8, u8, u8) = {
9193/// "red" => (255, 0, 0),
9294/// "green" => (0, 255, 0),
@@ -98,13 +100,77 @@ macro_rules! match_ignore_ascii_case {
98100/// ```
99101///
100102/// You can also iterate over the map entries by using `keywords::entries()`.
103+ macro_rules! ascii_case_insensitive_map {
104+ ( static $name: ident : $ValueType: ty = { $( $key: tt => $value: expr ) ,+ } ) => {
105+ ascii_case_insensitive_map!( static $name : $ValueType = { $( $key => $value, ) + } )
106+ } ;
107+ ( static $name: ident : $ValueType: ty = { $( $key: tt => $value: expr, ) + } ) => {
108+
109+ // While the obvious choice for this would be an inner module, it's not possible to
110+ // reference from types from there, see:
111+ // <https://github.com/rust-lang/rust/issues/114369>
112+ //
113+ // So we abuse a struct with static associated functions instead.
114+ #[ allow( non_camel_case_types) ]
115+ struct $name;
116+ impl $name {
117+ #[ allow( dead_code) ]
118+ fn entries( ) -> impl Iterator <Item = ( & ' static & ' static str , & ' static $ValueType) > {
119+ [ $( ( & $key, & $value) , ) * ] . iter( ) . copied( )
120+ }
121+
122+ fn get( input: & str ) -> Option <& ' static $ValueType> {
123+ $crate:: match_ignore_ascii_case!( input,
124+ $( $key => Some ( & $value) , ) *
125+ _ => None ,
126+ )
127+ }
128+ }
129+ }
130+ }
131+
132+ #[ cfg( feature = "fast_match_color" ) ]
133+ #[ macro_export]
134+ /// Define a function `$name(&str) -> Option<&'static $ValueType>`
135+ ///
136+ /// The function finds a match for the input string
137+ /// in a [`phf` map](https://github.com/sfackler/rust-phf)
138+ /// and returns a reference to the corresponding value.
139+ /// Matching is case-insensitive in the ASCII range.
140+ ///
141+ /// ## Example:
142+ ///
143+ /// ```rust
144+ /// # fn main() {} // Make doctest not wrap everything in its own main
145+ ///
146+ /// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
147+ /// cssparser::ascii_case_insensitive_map! {
148+ /// static KEYWORDS : (u8, u8, u8) = {
149+ /// "red" => (255, 0, 0),
150+ /// "green" => (0, 255, 0),
151+ /// "blue" => (0, 0, 255),
152+ /// }
153+ /// }
154+ /// KEYWORDS::get(input).cloned()
155+ /// }
156+ /// ```
157+ ///
158+ /// You can also iterate over the map entries by using `keywords::entries()`.
159+ macro_rules! ascii_case_insensitive_map {
160+ ( $( $any: tt) +) => {
161+ $crate:: ascii_case_insensitive_phf_map!( $( $any) +) ;
162+ } ;
163+ }
164+
165+ /// Fast implementation of `ascii_case_insensitive_map!` using a phf map.
166+ /// See `ascii_case_insensitive_map!` above for docs
167+ #[ cfg( feature = "fast_match_color" ) ]
101168#[ macro_export]
102169macro_rules! ascii_case_insensitive_phf_map {
103170 ( static $name: ident : $ValueType: ty = { $( $key: tt => $value: expr ) ,+ } ) => {
104171 ascii_case_insensitive_phf_map!( static $name : $ValueType = { $( $key => $value, ) + } )
105172 } ;
106173 ( static $name: ident : $ValueType: ty = { $( $key: tt => $value: expr, ) + } ) => {
107- use $crate:: _cssparser_internal_phf as phf;
108174
109175 #[ inline( always) ]
110176 const fn const_usize_max( a: usize , b: usize ) -> usize {
@@ -124,7 +190,7 @@ macro_rules! ascii_case_insensitive_phf_map {
124190 maxlen
125191 } ;
126192
127- static __MAP: phf:: Map <& ' static str , $ValueType> = phf:: phf_map! {
193+ static __MAP: :: phf:: Map <& ' static str , $ValueType> = :: phf:: phf_map! {
128194 $(
129195 $key => $value,
130196 ) *
0 commit comments