use std::mem::MaybeUninit;
#[macro_export]
macro_rules! match_ignore_ascii_case {
( $input:expr,
$(
$( #[$meta: meta] )*
$( $pattern: pat )|+ $( if $guard: expr )? => $then: expr
),+
$(,)?
) => {
{
mod cssparser_internal {
$crate::_cssparser_internal_max_len! {
$( $( $pattern )+ )+
}
}
$crate::_cssparser_internal_to_lowercase!($input, cssparser_internal::MAX_LENGTH => lowercase);
match lowercase.unwrap_or("A") {
$(
$( #[$meta] )*
$( $pattern )|+ $( if $guard )? => $then,
)+
}
}
};
}
#[macro_export]
macro_rules! ascii_case_insensitive_phf_map {
($name: ident -> $ValueType: ty = { $( $key: tt => $value: expr ),+ }) => {
ascii_case_insensitive_phf_map!($name -> $ValueType = { $( $key => $value, )+ })
};
($name: ident -> $ValueType: ty = { $( $key: tt => $value: expr, )+ }) => {
use $crate::_cssparser_internal_phf as phf;
mod cssparser_internal {
$crate::_cssparser_internal_max_len! {
$( $key )+
}
}
static MAP: phf::Map<&'static str, $ValueType> = phf::phf_map! {
$(
$key => $value,
)*
};
#[allow(non_camel_case_types)]
struct $name;
impl $name {
#[allow(dead_code)]
fn entries() -> impl Iterator<Item = (&'static &'static str, &'static $ValueType)> {
MAP.entries()
}
fn get(input: &str) -> Option<&'static $ValueType> {
$crate::_cssparser_internal_to_lowercase!(input, cssparser_internal::MAX_LENGTH => lowercase);
MAP.get(lowercase?)
}
}
}
}
#[inline(always)]
pub fn _cssparser_internal_create_uninit_array<const N: usize>() -> [MaybeUninit<u8>; N] {
unsafe {
MaybeUninit::<[MaybeUninit<u8>; N]>::uninit().assume_init()
}
}
#[macro_export]
#[doc(hidden)]
macro_rules! _cssparser_internal_to_lowercase {
($input: expr, $BUFFER_SIZE: expr => $output: ident) => {
let mut buffer = $crate::_cssparser_internal_create_uninit_array::<{ $BUFFER_SIZE }>();
let input: &str = $input;
let $output = $crate::_cssparser_internal_to_lowercase(&mut buffer, input);
};
}
#[doc(hidden)]
#[allow(non_snake_case)]
#[inline]
pub fn _cssparser_internal_to_lowercase<'a>(
buffer: &'a mut [MaybeUninit<u8>],
input: &'a str,
) -> Option<&'a str> {
let buffer = buffer.get_mut(..input.len())?;
#[cold]
fn make_ascii_lowercase<'a>(
buffer: &'a mut [MaybeUninit<u8>],
input: &'a str,
first_uppercase: usize,
) -> &'a str {
let input_bytes =
unsafe { &*(input.as_bytes() as *const [u8] as *const [MaybeUninit<u8>]) };
buffer.copy_from_slice(input_bytes);
let buffer = unsafe { &mut *(buffer as *mut [MaybeUninit<u8>] as *mut [u8]) };
buffer[first_uppercase..].make_ascii_lowercase();
unsafe { ::std::str::from_utf8_unchecked(buffer) }
}
Some(
match input.bytes().position(|byte| byte.is_ascii_uppercase()) {
Some(first_uppercase) => make_ascii_lowercase(buffer, input, first_uppercase),
None => input,
},
)
}