-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve internal DX around byte classification [1] #16864
Conversation
c3d9d8c
to
0639df7
Compare
4d0d459
to
3887c6b
Compare
This is a little proc macro that allows us to write the `enum Class` in a more ergonomic way.
This gets rid of the redundant `Class::CLASS_TABLE` ```diff - Class::CLASS_TABLE + Class::TABLE ```
This allows us to apply this change: ```diff - Class::CLASS_TABLE[cursor.curr as usize] + cursor.curr.classify() ``` Where `cursor.curr` is a `u8`
The `classify` method is implemented as `Class::CLASS_TABLE[*self as usize]` and uses an `#[inline(always)]` as well. This is just a DX improvement.
There is a tiny problem with the custom trait which exposes `classify()`. The moment you have 2 enums with `ClassifyBytes` in the same file, it means that the `trait U8Ext` was duplicated resulting in errors. To solve this, we can also implement the `From<u8> for #enum_name` trait. This allows us to just use `b'a'.into()` in a context where you are comparing it with an `Class::AlphaLower` for example.
In case the property starts with `--`, we will parse it as a CSS variable which can contain a few more characters like emoji for example. Initial reason that I included uppercase is because I was thinking about `Webkit`, but that should be `-webkit` in CSS anyway. Technically uppercase values are valid in CSS: ```css BODY { BACKGROUND-COLOR: RED; } ``` Play: https://play.tailwindcss.com/sUsWi0Ampe?file=css But for the sake of the arbitrary property, let's only allow lower-kebab-case property names.
3887c6b
to
54a1d6b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome stuff. Happy to see the CLASS_TABLE macro stuff gone honestly. Not really happy that this has to be its own crate but what can you do. Also unsure wether Char#into()
is super intuitive API but kinda also nice that it doesn't leak that it's a lookup table internally so maybe that's cool. Anyway no blockers from my side 👍
// If no fallback variant is found, default to "Other" | ||
let fallback_ident = fallback_variant.unwrap_or_else(|| Ident::new("Other", Span::call_site())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we error in the case no fallback variant is defined? Otherwise what happens if we don't define an Other
on the enum? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah we can be explicit here; In this PR I've always added the #[fallback]
anyway. Let me change it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implemented here:
@@ -102,7 +103,7 @@ impl Machine for ArbitraryPropertyMachine { | |||
// | |||
// E.g.: `[color:red]` | |||
// ^^^^^ | |||
Class::Alpha => cursor.advance(), | |||
Class::AlphaLower => cursor.advance(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sneaking in a behavioral change here I see 👀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤫
If you're missing the `#[fallback]` variant, you will see an error like this: ``` error: proc-macro derive panicked --> crates/oxide/src/extractor/string_machine.rs:71:45 | 71 | #[derive(Debug, Clone, Copy, PartialEq, Eq, ClassifyBytes)] | ^^^^^^^^^^^^^ | = help: message: A variant marked with #[fallback] is missing ```
This PR improves the internal DX when working with
u8
classification into a smaller enum. This is done by implementing aClassifyBytes
proc derive macro. The benefit of this is that the DX is much better and everything you will see here is done at compile time.Before:
After:
Before we were generating a
CLASS_TABLE
that we could access directly, but now it will be part of theClass
. This means that the usage has to change:This is slightly worse UX, and this is where another change comes in. We implemented the
From<u8> for #enum_name
trait inside of theClassifyBytes
derive macro. This allows us to use.into()
on anyu8
as long as we are comparing it to aClass
instance. In our scenario:Usage wise, this looks something like this:
If you manually look at the
Class::TABLE
in your editor for example, you can see that it is properly generated at compile time.Given this input:
This is the result:
