Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
495751c
Add generic trait for method parameters
alexvbrdn Jul 1, 2025
8abe573
WIP
alexvbrdn Jul 6, 2025
1e7ec95
WIP
alexvbrdn Jul 8, 2025
9cf30a6
WIP
alexvbrdn Jul 10, 2025
671f3a3
WIP
alexvbrdn Jul 10, 2025
75c06b3
add parallel intersection
alexvbrdn Jul 27, 2025
b37ef65
WIP
alexvbrdn Jul 28, 2025
3ea0dec
update readme
alexvbrdn Jul 29, 2025
a47c779
rename methods
alexvbrdn Aug 2, 2025
bcc9d7d
Update description
alexvbrdn Aug 2, 2025
8d5b66e
Update docs
alexvbrdn Aug 2, 2025
90c462b
update
alexvbrdn Aug 3, 2025
7884f73
update most descriptions
alexvbrdn Aug 3, 2025
eb79826
fix bench
alexvbrdn Aug 3, 2025
691a972
fix docs test
alexvbrdn Aug 3, 2025
4fe1d94
update docs
alexvbrdn Aug 3, 2025
a42c87a
Update README.md
alexvbrdn Aug 4, 2025
aec5c39
Update naming and docs
alexvbrdn Aug 4, 2025
19aef3f
improve test
alexvbrdn Aug 4, 2025
6878356
Fix bad repetition case
alexvbrdn Aug 6, 2025
29697f8
fix algo repeat
alexvbrdn Aug 8, 2025
e24624e
update serialization
alexvbrdn Aug 9, 2025
f874caa
remove some errors
alexvbrdn Aug 11, 2025
c2cc842
Change regex convertion algo
alexvbrdn Sep 16, 2025
135cca6
update tests
alexvbrdn Sep 16, 2025
c3d800a
fix clippy
alexvbrdn Sep 16, 2025
afbacc6
add test
alexvbrdn Sep 16, 2025
7b576f7
update readme
alexvbrdn Sep 16, 2025
0a0d91b
update readme
alexvbrdn Sep 16, 2025
05b6802
update method signature
alexvbrdn Sep 16, 2025
a2dc371
add concat all for regex
alexvbrdn Sep 17, 2025
7afac62
update docs
alexvbrdn Sep 19, 2025
2119ea6
update doc
alexvbrdn Sep 19, 2025
0315e7d
additional updates
alexvbrdn Sep 19, 2025
1fd6bfc
update readme
alexvbrdn Sep 19, 2025
499735d
update docs
alexvbrdn Sep 20, 2025
b67597d
update method signatures
alexvbrdn Sep 21, 2025
c243522
fix failed build
alexvbrdn Sep 21, 2025
02852f9
fix serialization
alexvbrdn Sep 24, 2025
9a1266f
Huge improvements in generate strings
alexvbrdn Oct 2, 2025
fb5eb1a
Fix bad implementation of to_embedding
alexvbrdn Oct 3, 2025
1e4980b
improve assert_not_timed_out clock cycle
alexvbrdn Oct 3, 2025
68e87c4
Parallelize state selection for elimination
alexvbrdn Oct 8, 2025
863fdce
Fix misuse of hashmap for determinize
alexvbrdn Oct 8, 2025
2dcf141
improve generate_strings + fix clippy issues
alexvbrdn Mar 17, 2026
06377a0
Fix generate_strings recomputing strings in offset
alexvbrdn Mar 18, 2026
cac1a5d
Add Hopcroft minimization algorithm
alexvbrdn Mar 21, 2026
284bad6
Update generate_strings
alexvbrdn Mar 21, 2026
aced1ab
Fix generate_strings
alexvbrdn Mar 21, 2026
7c10284
Fix buggy automaton to regex conversion
alexvbrdn Apr 18, 2026
0cc654c
remove serialization
alexvbrdn Apr 19, 2026
cc793ff
Make remove_dead_transitions public
alexvbrdn Apr 23, 2026
5856ebc
Rename method
alexvbrdn Apr 23, 2026
4b41ff3
Add new method to unaccept a state
alexvbrdn May 6, 2026
9bba5b4
Make methods public
alexvbrdn May 23, 2026
2529e58
A lot of small bug fixes
alexvbrdn Jun 3, 2026
d8d8fef
WIP: Improve testing and redesign lib
alexvbrdn Jun 4, 2026
d37ac9a
Big refactoring
alexvbrdn Jun 5, 2026
4c2f063
Update README.md
alexvbrdn Jun 5, 2026
eacd8a9
Remove minimize execution profile
alexvbrdn Jun 5, 2026
518ec3b
Some lib updates
alexvbrdn Jun 9, 2026
7fd08dc
Big refactoring
alexvbrdn Jun 14, 2026
90d0519
Some fixes and improvements
alexvbrdn Jul 2, 2026
70c3a03
Add Cargo.lock
alexvbrdn Jul 2, 2026
28a4058
Some additional fixes
alexvbrdn Jul 3, 2026
017bd3f
Make ExecutionProfile::assert_* public
alexvbrdn Jul 17, 2026
098dc3e
Fix failing CI
alexvbrdn Jul 17, 2026
26c6a61
Fix clippy issue
alexvbrdn Jul 17, 2026
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
64 changes: 56 additions & 8 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,65 @@ name: Publish to crates.io
on:
push:
tags:
- 'v*'
- "v*"

permissions:
contents: read

env:
CARGO_TERM_COLOR: always
RUSTDOCFLAGS: -D warnings

jobs:
build:
publish:
runs-on: ubuntu-latest
# Gate publishing behind a protected GitHub environment so the crates.io
# token is only exposed to reviewed, tag-triggered runs. Configure required
# reviewers on this environment in the repository settings.
environment: crates-io
steps:
- uses: actions/checkout@v4
- uses: actions-rs/toolchain@v1
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master
with:
toolchain: stable
override: true
- uses: katyo/publish-crates@v2
toolchain: stable
components: rustfmt, clippy

# Never publish a crate whose version disagrees with the pushed tag.
- name: Verify tag matches Cargo.toml version
run: |
crate_version="$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')"
tag_version="${GITHUB_REF_NAME#v}"
if [ "$crate_version" != "$tag_version" ]; then
echo "::error::Tag ${GITHUB_REF_NAME} (${tag_version}) does not match Cargo.toml version ${crate_version}"
exit 1
fi

- name: Format
run: cargo fmt --all -- --check
- name: Lint
run: |
cargo clippy --locked --all-targets -- -D warnings
cargo clippy --locked --no-default-features --all-targets -- -D warnings
- name: Test
run: |
cargo test --locked
cargo test --locked --no-default-features
- name: Docs
run: cargo doc --locked --no-deps

# Also verify the declared MSRV before publishing, like CI does.
- name: Read MSRV from Cargo.toml
id: msrv
run: echo "msrv=$(grep -m1 '^rust-version' Cargo.toml | cut -d'"' -f2)" >> "$GITHUB_OUTPUT"
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master
with:
registry-token: ${{ secrets.CRATES_API_TOKEN }}
toolchain: ${{ steps.msrv.outputs.msrv }}
- name: Check on MSRV
run: |
cargo +${{ steps.msrv.outputs.msrv }} check --locked --all-features
cargo +${{ steps.msrv.outputs.msrv }} check --locked --no-default-features

- name: Publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_API_TOKEN }}
run: cargo +stable publish --locked
63 changes: 54 additions & 9 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,68 @@ name: Rust

on:
push:
branches: [ "main" ]
branches: ["main", "v1"]
pull_request:
branches: [ "main" ]
workflow_dispatch:

permissions:
contents: read

env:
CARGO_TERM_COLOR: always
RUSTDOCFLAGS: -D warnings

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master
with:
toolchain: stable
components: rustfmt, clippy
- name: Format
run: cargo fmt --all -- --check
- name: Build
run: cargo build --locked --verbose
- name: Test & Lint
run: |
cargo test --locked
cargo clippy --locked --all-targets -- -D warnings
- name: Test & Lint (no default features)
run: |
cargo test --locked --no-default-features
cargo clippy --locked --no-default-features --all-targets -- -D warnings
- name: Docs
run: cargo doc --locked --no-deps

# Keep the declared `rust-version` (MSRV) honest, for both feature configs.
msrv:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
# Single source of truth: the MSRV comes from Cargo.toml.
- name: Read MSRV from Cargo.toml
id: msrv
run: echo "msrv=$(grep -m1 '^rust-version' Cargo.toml | cut -d'"' -f2)" >> "$GITHUB_OUTPUT"
- uses: dtolnay/rust-toolchain@fa04a1451ff1842e2626ccb99004d0195b455a88 # master
with:
toolchain: ${{ steps.msrv.outputs.msrv }}
- name: Check on MSRV
run: |
cargo check --locked --all-features
cargo check --locked --no-default-features

audit:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write # audit-check files an issue when a vulnerability is found

steps:
- uses: actions/checkout@v4
- name: Build
run: cargo build --all-features --verbose
- name: Test & Lint
run: |
cargo test --all-features
cargo clippy --all-features
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: rustsec/audit-check@69366f33c96575abad1ee0dba8212993eecbe998 # v2.0.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
9 changes: 4 additions & 5 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

Expand All @@ -18,4 +14,7 @@ Cargo.lock
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
#.idea/

# cargo mutants output
mutants.out*/
128 changes: 128 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Changelog

All notable changes to this crate are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased] - upcoming 1.0.0

This is a major redesign of the public API around the `Term` enum (wrapping
either a `RegularExpression` or a `FastAutomaton`), which dispatches each
operation to the cheaper representation when possible. See the crate-level
docs for the architecture. Almost the entire public surface changed; highlights
below.

### Added
- New `Term` constructors and conversions: `new_empty`, `new_total`,
`new_empty_string`, `from_pattern`, `from_regex(RegularExpression)`,
`from_automaton(FastAutomaton)`, plus `From<RegularExpression>`,
`From<FastAutomaton>`, `FromStr`, `Display`, and `Default` (= `new_empty`).
- New `Term` operations: `concat`, `complement`, `determinize`, `minimize`,
`matches`, `is_deterministic`, `is_minimal`, `is_finite`, `to_pattern`, and
`iter_strings` (lazy `StringGenerator` iterator).
- `RegularExpression::MAX_NESTING_DEPTH` and a depth check in `to_automaton`
that returns the new `EngineError::RegexTooDeeplyNested` for hand-built trees
nested past the limit, instead of overflowing the stack.
- `to_automaton` returns `Cow` to avoid unnecessary cloning; `to_regex`
returns `Result<Cow<…>, EngineError>` (see Changed — it is now fallible).
- `FastAutomaton` gained corresponding low-level constructors/operations
(`new_empty`, `new_total`, `new_empty_string`, `determinize`, `minimize`
using Hopcroft's algorithm, `is_minimal`, `unaccept`, `print_dot`,
`try_add_transition`) and inspection helpers (`states`, `direct_states`,
`transitions_from`, `transitions_to_vec`, `has_transition`, ...).
- New `EngineError` variants: `InvalidRepetitionBounds`,
`IncompatibleSpanningSet`, `DeterministicAutomatonRequired`,
`UnsupportedRegexFeature`, `RegexTooDeeplyNested`; the enum is now
`#[non_exhaustive]`.
- `tracing` instrumentation on the core `Term`, `FastAutomaton`, and
`RegularExpression` operations (concat, union, intersection, difference,
complement, repeat, determinize, minimize, equivalence/subset checks,
string generation, conversions). No-op unless a `tracing` subscriber is
installed.
- Parallel (Rayon-backed) variants of union/intersection for >3 operands,
gated behind the default-on `parallel` feature, with sequential fallbacks
for `--no-default-features`.
- `cargo fmt --check`, `cargo clippy -- -D warnings`, `cargo doc --no-deps`
(with `RUSTDOCFLAGS=-D warnings`), and a dependency vulnerability audit
(`rustsec/audit-check`) to CI.
- `regex_charclass` is re-exported at the crate root, so automata can be
built by hand (`Char`, `CharRange`) without adding a separately
version-matched dependency.
- `NoHashHasher`, the crate-owned no-op hasher behind the `IntSet` state-id
sets (replaces the `nohash-hasher` dependency, keeping 0.x types out of
the public API).
- `EngineError` implements `Clone`; `StringGenerator` implements `Debug` and
`FusedIterator`; `ExecutionProfileBuilder` implements `Debug` and `Clone`.

### Changed
- `Term::to_regex`/`to_pattern` and `FastAutomaton::to_regex` are now fallible
(`Result<_, EngineError>`) and honor the `ExecutionProfile` timeout, since
state elimination can grow super-polynomially on adversarial automata.
`Term`'s `Display` therefore renders a pattern only for regex-backed terms;
automaton-backed terms display as Graphviz DOT (use `to_pattern` for a
parseable pattern).
- `ExecutionProfile` redesigned as an immutable, thread-local-aware config
built via the new `ExecutionProfileBuilder`, governing execution timeouts,
state-count limits, and an `implicit_determinization` toggle.
- `union`/`intersection`/`concat` now take
`impl IntoIterator<Item = impl Borrow<Term>>` instead of `&[Term]`, so
`&[a, b]`, `[&a, &b]`, and `Vec<Term>` all work without cloning.
- `repeat` now takes `impl RangeBounds<u32>` (e.g. `3..6`, `..=2`) instead of
explicit min/max parameters.
- `generate_strings` now takes `(limit, offset)` for pagination instead of a
single `count`.
- `is_empty`, `is_total`, and `is_empty_string` now return
`Result<bool, EngineError>` instead of `bool`.
- `are_equivalent`/`is_subset_of` renamed to `equivalent`/`subset`.
- `subtraction` renamed to `difference`, kept single-operand by design.
- Renamed `FastAutomaton::as_dot` to `to_dot` (old printing `to_dot` is now
`print_dot`), matching the crate's `to_*` convention for allocating
conversions (`to_pattern`, `to_regex`, `to_automaton`, `to_range`).
- Renamed `get_*` accessors to drop the `get_` prefix, per the Rust API
Guidelines' C-GETTER convention: `Term::get_length` to `length`,
`Term::get_cardinality` to `cardinality`, `FastAutomaton::get_length` to
`length`, `FastAutomaton::get_cardinality` to `cardinality`,
`FastAutomaton::get_number_of_states` to `number_of_states`,
`FastAutomaton::get_condition` to `condition`,
`FastAutomaton::get_start_state` to `start_state`,
`FastAutomaton::get_accept_states` to `accept_states`,
`FastAutomaton::get_spanning_set` to `spanning_set`,
`FastAutomaton::get_live_states` to `live_states`,
`FastAutomaton::get_spanning_bases` to `spanning_bases`,
`RegularExpression::get_length` to `length`,
`RegularExpression::get_cardinality` to `cardinality`,
`SpanningSet::get_spanning_ranges` to `spanning_ranges`,
`SpanningSet::get_number_of_spanning_ranges` to
`number_of_spanning_ranges`, `SpanningSet::get_spanning_range` to
`spanning_range`, `SpanningSet::get_rest` to `rest`,
`Condition::get_cardinality` to `cardinality`,
`Condition::get_binary_representation` to `binary_representation`,
`ConditionConverter::get_from_spanning_set`/`get_to_spanning_set` to
`from_spanning_set`/`to_spanning_set`.
- Error messages follow the std convention (lowercase, no trailing
punctuation) so they compose cleanly when wrapped by callers.
- Edition bumped to 2024 and `Cargo.toml` metadata (`description`,
`categories`) updated.

### Removed
- The `serde` feature and all serialization, FAIR (base85) encoding,
encryption, and compression support (`serde`, `ciborium`, `z85`,
`aes-gcm-siv`, `sha2`, `flate2` dependencies).
- `Term::get_details` and the `Details` type.
- The `tokenizer` module.
- Unused `log`, `rand`, and `lazy_static` dependencies, and the `regex`
crate dependency (now dev-only, used by integration tests).
- The `nohash-hasher` dependency (replaced by the crate-owned
`NoHashHasher`; see Added).
- `EngineError` variants `AutomatonShouldBeDeterministic`, `TooMuchTerms`,
`ConditionIndexOutOfBound`, `TokenError`, and the `is_server_error` method.
- The `max_number_of_terms` execution-profile limit (no longer enforced).

## Earlier releases

Releases prior to 1.0.0 (`v0.1.0` through `v0.3.1`) predate this changelog;
see the [GitHub tags](https://github.com/RegexSolver/regexsolver/tags) and
commit history for details.

[Unreleased]: https://github.com/RegexSolver/regexsolver/compare/v0.3.1...HEAD
Loading
Loading