diff --git a/Cargo.toml b/Cargo.toml index 25de0a19..414b4e03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cssparser" -version = "0.37.0" +version = "0.38.0" authors = ["Simon Sapin "] description = "Rust implementation of CSS Syntax Level 3" diff --git a/color/Cargo.toml b/color/Cargo.toml index 93e35b44..13153144 100644 --- a/color/Cargo.toml +++ b/color/Cargo.toml @@ -13,7 +13,7 @@ rust-version = "1.85" path = "lib.rs" [dependencies] -cssparser = { path = "..", version = "0.37", default-features = false } +cssparser = { path = "..", version = "0.38", default-features = false } serde = { version = "1.0", features = ["derive"], optional = true } [features] diff --git a/src/lib.rs b/src/lib.rs index 60d59f83..0f48c1f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,9 +70,7 @@ fn parse_border_spacing(_context: &ParserContext, input: &mut Parser) pub use crate::cow_rc_str::CowRcStr; pub use crate::from_bytes::{stylesheet_encoding, EncodingSupport}; #[doc(hidden)] -pub use crate::macros::{ - _cssparser_internal_create_uninit_array, _cssparser_internal_to_lowercase, -}; +pub use crate::macros::_cssparser_internal_to_lowercase; pub use crate::nth::parse_nth; pub use crate::parser::{BasicParseError, BasicParseErrorKind, ParseError, ParseErrorKind}; pub use crate::parser::{Delimiter, Delimiters, Parser, ParserInput, ParserState}; diff --git a/src/macros.rs b/src/macros.rs index 81dc223a..6038f32e 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -61,7 +61,9 @@ macro_rules! match_ignore_ascii_case { maxlen }; - $crate::_cssparser_internal_to_lowercase!($input, MAX_LENGTH => lowercase); + let mut buffer = [const { core::mem::MaybeUninit::::uninit() }; MAX_LENGTH]; + let input: &str = $input; // Extend lifetime of temporaries + let lowercase = $crate::_cssparser_internal_to_lowercase(&mut buffer, input); // "A" is a short string that we know is different for every string pattern, // since we’ve verified that none of them include ASCII upper case letters. match lowercase.unwrap_or("A") { @@ -210,40 +212,14 @@ macro_rules! ascii_case_insensitive_phf_map { } fn get(input: &str) -> Option<&'static $ValueType> { - $crate::_cssparser_internal_to_lowercase!(input, MAX_LENGTH => lowercase); - __MAP.get(lowercase?) + let mut buffer = [const { core::mem::MaybeUninit::::uninit() }; MAX_LENGTH]; + let lowercase = $crate::_cssparser_internal_to_lowercase(&mut buffer, input)?; + __MAP.get(lowercase) } } } } -/// Create a new array of MaybeUninit items, in an uninitialized state. -#[inline(always)] -pub fn _cssparser_internal_create_uninit_array() -> [MaybeUninit; N] { - unsafe { - // SAFETY: An uninitialized `[MaybeUninit<_>; LEN]` is valid. - // See: https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#method.uninit_array - MaybeUninit::<[MaybeUninit; N]>::uninit().assume_init() - } -} - -/// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros. -/// -/// **This macro is not part of the public API. It can change or be removed between any versions.** -/// -/// Define a local variable named `$output` -/// and assign it the result of calling `_cssparser_internal_to_lowercase` -/// with a stack-allocated buffer of length `$BUFFER_SIZE`. -#[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); - }; -} - /// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros. /// /// **This function is not part of the public API. It can change or be removed between any versions.** diff --git a/src/tests.rs b/src/tests.rs index 2f54d98b..21e8d856 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1150,6 +1150,17 @@ fn procedural_masquerade_whitespace() { } } +#[test] +fn test_match_ignore_ascii_case_with_temporary_borrow() { + fn generate_string() -> String { + "test".to_owned() + } + assert!(match_ignore_ascii_case! { &generate_string(), + "test" => true, + _ => false, + }); +} + #[test] fn parse_until_before_stops_at_delimiter_or_end_of_input() { // For all j and k, inputs[i].1[j] should parse the same as inputs[i].1[k]