Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinMalfait committed Feb 12, 2025
1 parent a2995a2 commit 15c95dd
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 35 deletions.
76 changes: 50 additions & 26 deletions crates/oxide/src/extractor/candidate_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -250,41 +256,59 @@ 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();
let mut cursor = Cursor::new(input.as_bytes());

let mut actual: Vec<&str> = vec![];

dbg!(&input);

for i in 0..input.len() {
cursor.move_to(i);

Expand Down
22 changes: 13 additions & 9 deletions crates/oxide/src/extractor/named_variant_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
//
Expand All @@ -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(),
Expand Down
4 changes: 4 additions & 0 deletions crates/oxide/src/extractor/variant_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]:"]),
Expand Down

0 comments on commit 15c95dd

Please sign in to comment.