From 15c95dd73b2f37b04fe5c4ba9489e1f777b6c267 Mon Sep 17 00:00:00 2001 From: Robin Malfait Date: Wed, 12 Feb 2025 17:50:45 +0100 Subject: [PATCH] WIP --- .../oxide/src/extractor/candidate_machine.rs | 76 ++++++++++++------- .../src/extractor/named_variant_machine.rs | 22 +++--- crates/oxide/src/extractor/variant_machine.rs | 4 + 3 files changed, 67 insertions(+), 35 deletions(-) diff --git a/crates/oxide/src/extractor/candidate_machine.rs b/crates/oxide/src/extractor/candidate_machine.rs index 7e173cc2dbcf..6043a8a75fc6 100644 --- a/crates/oxide/src/extractor/candidate_machine.rs +++ b/crates/oxide/src/extractor/candidate_machine.rs @@ -42,6 +42,10 @@ impl Machine for CandidateMachine { None => {} } + // let so_far = std::str::from_utf8(&cursor.input[self.start_pos..=cursor.pos]); + // dbg!(so_far); + // eprintln!("{}", &cursor); + match self.state { State::Idle => match (cursor.curr, cursor.next) { // Candidates don't start with `--`, skip ahead @@ -142,6 +146,8 @@ impl Machine for CandidateMachine { } (MachineState::Parsing, state @ MachineState::Done(span)) => { + // TODO: Ensure the variant is parsing but incomplete + // match self.last_variant_end_pos { // There's a variant, but the variant and utility are not touching. Some(end_pos) if end_pos + 1 > span.start => state, @@ -250,34 +256,50 @@ mod tests { #[test] fn test_candidate_extraction() { for (input, expected) in [ - // Simple utility - ("flex", vec!["flex"]), - // Single character utility - ("a", vec!["a"]), - // Simple utility with dashes - ("items-center", vec!["items-center"]), - // Simple utility with numbers - ("px-2.5", vec!["px-2.5"]), - // Simple variant with simple utility - ("hover:flex", vec!["hover:flex"]), - // Arbitrary properties - ("[color:red]", vec!["[color:red]"]), - ("![color:red]", vec!["![color:red]"]), - ("[color:red]!", vec!["[color:red]!"]), - ("[color:red]/20", vec!["[color:red]/20"]), - ("![color:red]/20", vec!["![color:red]/20"]), - ("[color:red]/20!", vec!["[color:red]/20!"]), - // With multiple variants - ("hover:focus:flex", vec!["hover:focus:flex"]), - // With complex variants - ( - "[&>[data-slot=icon]:last-child]:right-2.5", - vec!["[&>[data-slot=icon]:last-child]:right-2.5"], - ), - // With multiple (complex) variants + //// // Simple utility + //// ("flex", vec!["flex"]), + //// // Single character utility + //// ("a", vec!["a"]), + //// // Simple utility with dashes + //// ("items-center", vec!["items-center"]), + //// // Simple utility with numbers + //// ("px-2.5", vec!["px-2.5"]), + //// // Simple variant with simple utility + //// ("hover:flex", vec!["hover:flex"]), + //// // Arbitrary properties + //// ("[color:red]", vec!["[color:red]"]), + //// ("![color:red]", vec!["![color:red]"]), + //// ("[color:red]!", vec!["[color:red]!"]), + //// ("[color:red]/20", vec!["[color:red]/20"]), + //// ("![color:red]/20", vec!["![color:red]/20"]), + //// ("[color:red]/20!", vec!["[color:red]/20!"]), + //// // With multiple variants + //// ("hover:focus:flex", vec!["hover:focus:flex"]), + //// // With complex variants + //// ( + //// "[&>[data-slot=icon]:last-child]:right-2.5", + //// vec![ + //// "icon", + //// "last-child", + //// "[&>[data-slot=icon]:last-child]:right-2.5", + //// ], + //// ), + //// // With multiple (complex) variants + //// ( + //// "[&>[data-slot=icon]:last-child]:sm:right-2.5", + //// vec![ + //// "icon", + //// "last-child", + //// "[&>[data-slot=icon]:last-child]:sm:right-2.5", + //// ], + //// ), ( "sm:[&>[data-slot=icon]:last-child]:right-2.5", - vec!["sm:[&>[data-slot=icon]:last-child]:right-2.5"], + vec![ + "icon", + "last-child", + "sm:[&>[data-slot=icon]:last-child]:right-2.5", + ], ), ] { let mut machine = CandidateMachine::default(); @@ -285,6 +307,8 @@ mod tests { let mut actual: Vec<&str> = vec![]; + dbg!(&input); + for i in 0..input.len() { cursor.move_to(i); diff --git a/crates/oxide/src/extractor/named_variant_machine.rs b/crates/oxide/src/extractor/named_variant_machine.rs index 975f80b0db60..2b55478c6df3 100644 --- a/crates/oxide/src/extractor/named_variant_machine.rs +++ b/crates/oxide/src/extractor/named_variant_machine.rs @@ -82,12 +82,12 @@ impl Machine for NamedVariantMachine { _ => MachineState::Idle, }, - State::Parsing => match (cursor.prev, cursor.curr, cursor.next) { + State::Parsing => match (cursor.curr, cursor.next) { // Start of an arbitrary value - (_, b'-', b'[') => self.parse_arbitrary_value(), + (b'-', b'[') => self.parse_arbitrary_value(), // Start of an arbitrary variable - (_, b'-', b'(') => self.parse_arbitrary_variable(), + (b'-', b'(') => self.parse_arbitrary_variable(), // Valid characters _if_ followed by another valid character. These characters are // only valid inside of the variant but not at the end of the variant. @@ -98,12 +98,13 @@ impl Machine for NamedVariantMachine { // ^ // E.g.: `hover-/` // ^ - (_, b'-' | b'_', b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9') => MachineState::Parsing, + ( + b'-' | b'_', // + b'-' | b'_' | b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9', + ) => MachineState::Parsing, // Still valid characters - (_, b'_' | b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'*', _) => { - MachineState::Parsing - } + (b'_' | b'a'..=b'z' | b'A'..=b'Z' | b'0'..=b'9' | b'*', _) => MachineState::Parsing, // A `/` means we are at the end of the variant, but there might be a modifier // @@ -113,13 +114,16 @@ impl Machine for NamedVariantMachine { // group-hover/name: // ^ // ``` - (_, b'/', _) => self.parse_modifier(), + (b'/', _) => { + self.modifier_machine.next(cursor); + self.parse_modifier() + } // A `:` means we are at the end of the variant // // E.g.: `hover:` // ^ - (_, b':', _) => self.done(self.start_pos, cursor), + (b':', _) => self.done(self.start_pos, cursor), // Everything else is invalid _ => self.restart(), diff --git a/crates/oxide/src/extractor/variant_machine.rs b/crates/oxide/src/extractor/variant_machine.rs index 3d88cbeb7c40..2d5b26a91a13 100644 --- a/crates/oxide/src/extractor/variant_machine.rs +++ b/crates/oxide/src/extractor/variant_machine.rs @@ -154,6 +154,10 @@ mod tests { "[&>[data-slot=icon]:last-child]:", vec!["[&>[data-slot=icon]:last-child]:"], ), + ( + "sm:[&>[data-slot=icon]:last-child]:", + vec!["sm:", "[&>[data-slot=icon]:last-child]:"], + ), // Modifiers ("group-hover/foo:flex", vec!["group-hover/foo:"]), ("group-hover/[.parent]:flex", vec!["group-hover/[.parent]:"]),