Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,25 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: |
pip install --upgrade pip wheel
pip install --editable .
- name: Test with bikeshed
- name: Build Rust extension
run: |
pip install maturin
maturin build --release
pip install --force-reinstall --find-links rust/target/wheels bikeshed_rust
- name: Test with bikeshed (Python mode)
run: bikeshed --no-update test
env:
BIKESHED_USE_RUST: '0'
- name: Test with bikeshed (Rust mode)
run: bikeshed --no-update test
env:
BIKESHED_USE_RUST: '1'

lint:

Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ node_modules/
/playwright/.cache/
/env
/docs/*.html
/html-perf-test
/rust/target/
/html-perf-test
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ though most such specs have switched their source file extensions to `.bs` now.
Using `.src.html` in most text editors will display the file with HTML source formatting,
which isn't generally what you want.)

Rust
-----------

Bikeshed includes optional Rust extensions, in an effort to port some or all of the code into Rust.

To enable: `export BIKESHED_USE_RUST=1`

License
-------

Expand Down
2 changes: 1 addition & 1 deletion bikeshed/h/parser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from ... import config, constants, t
from ... import messages as m
from . import preds
from . import preds_wrapper as preds
from .nodes import (
Comment,
Doctype,
Expand Down
82 changes: 82 additions & 0 deletions bikeshed/h/parser/preds_wrapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from __future__ import annotations

import os

_USE_RUST = os.environ.get("BIKESHED_USE_RUST", "").lower() in ("1", "true")

if _USE_RUST:
try:
import bikeshed_rust
from . import preds as _preds

isASCII = bikeshed_rust.is_ascii
isASCIIAlpha = bikeshed_rust.is_ascii_alpha
isASCIIAlphanum = bikeshed_rust.is_ascii_alphanum
isASCIILowerAlpha = bikeshed_rust.is_ascii_lower_alpha
isASCIIUpperAlpha = bikeshed_rust.is_ascii_upper_alpha
isAttrNameChar = bikeshed_rust.is_attr_name_char
isControl = bikeshed_rust.is_control
isDigit = bikeshed_rust.is_digit
isHexDigit = bikeshed_rust.is_hex_digit
isNoncharacter = bikeshed_rust.is_noncharacter
isTagnameChar = bikeshed_rust.is_tagname_char
isWhitespace = bikeshed_rust.is_whitespace

charRefs = _preds.charRefs
xmlishTagnames = _preds.xmlishTagnames
isXMLishTagname = _preds.isXMLishTagname
except ImportError:
from . import preds as _preds

charRefs = _preds.charRefs
xmlishTagnames = _preds.xmlishTagnames
isASCII = _preds.isASCII
isASCIIAlpha = _preds.isASCIIAlpha
isASCIIAlphanum = _preds.isASCIIAlphanum
isASCIILowerAlpha = _preds.isASCIILowerAlpha
isASCIIUpperAlpha = _preds.isASCIIUpperAlpha
isAttrNameChar = _preds.isAttrNameChar
isControl = _preds.isControl
isDigit = _preds.isDigit
isHexDigit = _preds.isHexDigit
isNoncharacter = _preds.isNoncharacter
isTagnameChar = _preds.isTagnameChar
isWhitespace = _preds.isWhitespace
isXMLishTagname = _preds.isXMLishTagname

else:
from . import preds as _preds

charRefs = _preds.charRefs
xmlishTagnames = _preds.xmlishTagnames
isASCII = _preds.isASCII
isASCIIAlpha = _preds.isASCIIAlpha
isASCIIAlphanum = _preds.isASCIIAlphanum
isASCIILowerAlpha = _preds.isASCIILowerAlpha
isASCIIUpperAlpha = _preds.isASCIIUpperAlpha
isAttrNameChar = _preds.isAttrNameChar
isControl = _preds.isControl
isDigit = _preds.isDigit
isHexDigit = _preds.isHexDigit
isNoncharacter = _preds.isNoncharacter
isTagnameChar = _preds.isTagnameChar
isWhitespace = _preds.isWhitespace
isXMLishTagname = _preds.isXMLishTagname

__all__ = [
"charRefs",
"xmlishTagnames",
"isASCII",
"isASCIIAlpha",
"isASCIIAlphanum",
"isASCIILowerAlpha",
"isASCIIUpperAlpha",
"isAttrNameChar",
"isControl",
"isDigit",
"isHexDigit",
"isNoncharacter",
"isTagnameChar",
"isWhitespace",
"isXMLishTagname",
]
17 changes: 15 additions & 2 deletions bikeshed/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@
from . import messages as m
from .Spec import Spec


def _getTestTitle() -> str:
try:
from .h.parser import preds_wrapper
# Check if we're using the Rust implementation
if hasattr(preds_wrapper, 'isASCII'):
module = getattr(preds_wrapper.isASCII, '__module__', '')
if 'bikeshed_rust' in module:
return "Running tests [R]"
except Exception:
pass
return "Running tests"

if t.TYPE_CHECKING:
import argparse

Expand Down Expand Up @@ -101,7 +114,7 @@ def run(
numPassed = 0
total = 0
fails = []
pathProgress = alive_it(paths, dual_line=True, length=20)
pathProgress = alive_it(paths, dual_line=True, length=20, title=_getTestTitle())
try:
for path in pathProgress:
testName = testNameForPath(path)
Expand Down Expand Up @@ -149,7 +162,7 @@ def rebase(
if len(paths) == 0:
m.p("No tests were found.")
return True
pathProgress = alive_it(paths, dual_line=True, length=20)
pathProgress = alive_it(paths, dual_line=True, length=20, title=_getTestTitle())
try:
for path in pathProgress:
testName = testNameForPath(path)
Expand Down
14 changes: 14 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
[build-system]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"

[project]
name = "bikeshed"
version = "0.1.0"
requires-python = ">=3.9"

[tool.maturin]
manifest-path = "rust/Cargo.toml"
module-name = "bikeshed_rust"
python-source = "bikeshed"

[tool.black]
line-length = 120

Expand Down
163 changes: 163 additions & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "bikeshed_rust"
version = "0.1.0"
edition = "2024"

[lib]
name = "bikeshed_rust"
crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.26", features = ["extension-module"] }

[profile.release]
lto = true
codegen-units = 1
strip = true
Loading
Loading