No description
Find a file
Robin Malfait de145c5b06
Refactor: use compile time type state pattern (#17083)
This PR implements the state machines using the type state pattern at
compile time (via generic types) instead of a runtime state variable.
There is no runtime check to see what state we are in, instead we
transition to the new state when it's necessary.

This has some nice performance improvements for some of the state
machines, e.g.:

```diff
- ArbitraryVariableMachine: Throughput: 744.92 MB/s
+ ArbitraryVariableMachine: Throughput:   1.21 GB/s
```

We also don't have to store the current state because each machine runs
to completion. It's during execution that we can move to a new state if
necessary.


Unfortunately the diff is a tiny bit annoying to read, but essentially
this is what happened:

### The `enum` is split up in it's individual states as structs:
```rs
enum State {
  A,
  B,
  C,
}
```
Becomes:
```rs
struct A;
struct B;
struct C;
```

### Generics

The current machine will receive a generic `State` that we can default
to the `IdleState`. Then we use `PhantomData` to "use" the type because
the generic type is otherwise not used as a concrete value, it's just a
marker.

```rs
struct MyMachine {}
```
Becomes:
```rs
struct MyMachine<State = Idle> {
  _state: std::marker::PhantomData<State>
}
```

### Split 

Next, the `next` function used to match on the current state, but now
each match arm is moved to a dedicated implementation instead:
```rs
impl Machine for MyMachine {
  fn next(&mut self) -> MachineState {
    match self.state {
      State::A => { /* … */ },
      State::B => { /* … */ },
      State::C => { /* … */ },
    }
  }
}
``` 
Becomes:
```rs
impl Machine for MyMachine<A> {
  fn next(&mut self) -> MachineState {
    /* … */
  }
}
impl Machine for MyMachine<B> {
  fn next(&mut self) -> MachineState {
    /* … */
  }
}
impl Machine for MyMachine<C> {
  fn next(&mut self) -> MachineState {
    /* … */
  }
}
```

It's a bit more verbose, but now each state is implemented in its own
block. This also removes 2 levels of nesting which is a nice benefit.
2025-03-10 14:08:39 -04:00
.github FreeBSD: rustup toolchain install 2025-03-05 12:48:24 +01:00
crates Refactor: use compile time type state pattern (#17083) 2025-03-10 14:08:39 -04:00
integrations Enable URL rewriting for PostCSS (#16965) 2025-03-07 12:18:10 +01:00
packages Prepare v4.0.12 release (#17033) 2025-03-07 12:38:53 +01:00
patches Upgrade @parcel/watcher to 2.5.1 (#16248) 2025-02-04 15:14:52 +01:00
playgrounds Update bun 1.2.3 → 1.2.4 (patch) (#16954) 2025-03-05 11:56:50 +01:00
scripts Prepare v4.0.1 release (#16018) 2025-01-29 14:14:35 -05:00
.gitignore Add test.debug to integration tests (#14133) 2024-08-08 12:02:19 +02:00
.npmrc introduce v4 codebase 2024-03-05 14:29:15 +01:00
.prettierignore Hoist oxide/crates to just crates (#13333) 2024-03-23 09:00:48 -04:00
Cargo.lock Improve internal DX around byte classification [1] (#16864) 2025-03-05 14:00:07 +01:00
Cargo.toml Hoist oxide/crates to just crates (#13333) 2024-03-23 09:00:48 -04:00
CHANGELOG.md Treat starting single quote as verbatim text in Slim (#17085) 2025-03-10 11:45:26 +01:00
LICENSE Add README, LICENSE, and CONTRIBUTING (#13088) 2024-03-05 14:45:39 -05:00
mise.toml Pin pnpm version in freebsd build 2025-02-25 18:20:14 +01:00
package.json Update tsup 8.3.6 → 8.4.0 (minor) (#16949) 2025-03-05 10:59:27 +00:00
pnpm-lock.yaml Update h3 1.15.0 → 1.15.1 (patch) (#17010) 2025-03-07 12:00:44 +01:00
pnpm-workspace.yaml Bump and pin prettier (#16382) 2025-02-10 10:54:45 +01:00
README.md Copy README file to every package (#13096) 2024-03-06 08:49:31 -05:00
rust-toolchain.toml Improve Oxide candidate extractor [0] (#16306) 2025-03-05 11:55:24 +01:00
turbo.json Revert: Only expose used CSS variables (#16403) 2025-02-10 13:26:13 +01:00
vitest.workspace.ts introduce v4 codebase 2024-03-05 14:29:15 +01:00

Tailwind CSS

A utility-first CSS framework for rapidly building custom user interfaces.

Build Status Total Downloads Latest Release License


Documentation

For full documentation, visit tailwindcss.com.

Community

For help, discussion about best practices, or any other conversation that would benefit from being searchable:

Discuss Tailwind CSS on GitHub

For chatting with others using the framework:

Join the Tailwind CSS Discord Server

Contributing

If you're interested in contributing to Tailwind CSS, please read our contributing docs before submitting a pull request.