diff --git a/.cargo/mutants.toml b/.cargo/mutants.toml new file mode 100644 index 00000000..d3987cda --- /dev/null +++ b/.cargo/mutants.toml @@ -0,0 +1,34 @@ +# cargo-mutants configuration + +# Skip the big end-to-end byte-identity test (covered by other cases that +# pinpoint failures more precisely). +additional_cargo_test_args = ["--skip", "test_by_testcase"] + +# Exclude mutations that produce runaway infinite loops in the parser. +# +# `parse_math_expression_with_math_mode` and helpers use `i += 1` (or similar +# `j += 1`, `depth += 1`) loop counters. Replacing those with `*=` or `-=` +# turns the counter into a no-op or makes it go backwards, producing an +# infinite loop that the test harness can only escape via timeout-kill. +# +# Each TIMEOUT mutant leaves behind a runaway test child that cargo-mutants +# SIGKILLs the cargo wrapper for, but the underlying test binary keeps +# running. Accumulated zombie test processes destabilize the GitHub-hosted +# runner, which then receives a shutdown signal and the entire job fails. +# +# These mutations are also INHERENTLY untestable by unit tests — detecting +# them would require timing-based assertions, which we explicitly avoid for +# deterministic CI. Excluding them here is a correctness fix, not a +# coverage hack: the algorithm correctness is verified by the broader +# byte-identity testcase suite. +exclude_re = [ + # `+=` → `*=` turns `i += 1` into `i *= 1` (no-op since i starts at 0). + 'replace \+= with \*=', + # `+=` → `-=` turns `i += 1` into `i -= 1` (counter goes backwards → + # infinite loop on underflow / repeated processing). + 'replace \+= with -=', + # `+=` → `/=` turns `i += 1` into `i /= 1` (no-op). + 'replace \+= with /=', + # `+=` → `%=` turns `i += 1` into `i %= 1` (i becomes 0, infinite loop). + 'replace \+= with %=', +] diff --git a/.github/workflows/mutants.yml b/.github/workflows/mutants.yml index 11c9f810..4d1cd0b6 100644 --- a/.github/workflows/mutants.yml +++ b/.github/workflows/mutants.yml @@ -15,7 +15,7 @@ on: - main paths: - '.github/workflows/mutants.yml' - - 'mutants.toml' + - '.cargo/mutants.toml' - 'Cargo.lock' - 'Cargo.toml' - 'libs/braillify/src/rules/math/encoder.rs' diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ce78842a..dc482e62 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -241,7 +241,7 @@ jobs: - dotnet-test steps: - uses: actions/checkout@v6 - - uses: changepacks/action@v0.1.0 + - uses: changepacks/action@main id: changepacks with: token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index ec8006a2..4580eda2 100644 --- a/.gitignore +++ b/.gitignore @@ -11,9 +11,45 @@ coverage cobertura.xml codecov codecov.* +*.profraw .DS_Store -._.DS_Store -**/.DS_Store +._.DS_Store +**/.DS_Store **/._.DS_Store .claude .omc +.omo +.sisyphus/ +.audit +trace_out.txt + +# Heap profiling output from `cargo bench --bench memory_dhat --features dhat-heap`. +# Generated artifact, not source. Regenerate locally if needed. +dhat-heap.json +**/dhat-heap.json + +# wasm-pack post-optimize transient (W11 build pipeline writes pkg/index_bg_opt.wasm +# then renames it over pkg/index_bg.wasm; if interrupted, the temp may linger). +# pkg/ itself is already covered by packages/node/.gitignore. +**/index_bg_opt.wasm + +# Playwright MCP output (screenshots, snapshots, console logs). +.playwright-mcp/ +**/.playwright-mcp/ + +# cargo-mutants output directories — generated per-run mutation reports. +# `mutants.toml` (the config) IS tracked; only outputs are ignored. +mutants.out/ +mutants.out.old/ +**/mutants.out/ +**/mutants.out.old/ + +# cargo-tarpaulin coverage outputs — `cargo tarpaulin --out Lcov` writes lcov.info +# to the workspace root; HTML/JSON reports drop tarpaulin-report.{html,json}. +# `cobertura.xml` is already ignored above. +lcov.info +**/lcov.info +tarpaulin-report.html +tarpaulin-report.json +**/tarpaulin-report.html +**/tarpaulin-report.json diff --git a/.oxlintrc.json b/.oxlintrc.json deleted file mode 100644 index 4356755a..00000000 --- a/.oxlintrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "$schema": "./node_modules/oxlint/configuration_schema.json", - "ignorePatterns": ["test_cases/**", "scripts/**"], - "extends": ["node_modules/eslint-plugin-devup/oxlintrc.json"] -} \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index e293d655..1aa03bdf 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -38,10 +38,21 @@ bun test test_cases/ # 테스트케이스 무결성 검증만 "note": "설명 (선택, 동일 input이 여럿이거나 맥락 필요 시에만)", "internal": "점자 내부표기", "expected": "브라유셀 인덱스 연결 문자열", - "unicode": "점자 유니코드 문자열" + "unicode": "점자 유니코드 문자열", + "world": "경쟁사(World) 점역 결과 (참고용, 수정 금지)", + "jeomsarang": "경쟁사(점사랑) 점역 결과 (참고용, 수정 금지)" } ``` +### ⚠️ `world` / `jeomsarang` 필드 — 경쟁사 benchmark (NEVER MODIFY, NEVER COMPARE) + +- `world`, `jeomsarang`은 **타 업체 점역 프로그램의 결과**를 그대로 보존한 참고용 필드다. +- **braillify의 정답이 아니다.** braillify의 정답은 오직 `unicode` (= `expected`)이며, PDF 규정에 근거한다. +- **절대로 수정하지 않는다.** input/internal을 정정하더라도 `world`/`jeomsarang`은 원본 그대로 둔다. +- **testcase 검수의 기준으로 사용하지 않는다.** `world`/`jeomsarang`이 우리 `unicode`와 다르더라도 testcase 오류 근거가 아니며, 그것들이 틀린 것은 braillify와 무관하다. +- **인코더 정답 비교 대상이 아니다.** `cargo test test_by_testcase`는 인코더 결과를 `expected`/`unicode`와만 비교한다. +- 이 필드의 존재 의도는 외부 점역 결과와의 차이를 관찰하기 위한 **읽기 전용 비교 자료**이지, 별도 지표가 되어서는 안 된다. + ### internal → expected/unicode 변환 `braillove-case-collector/converter.py`의 패턴을 따른다: @@ -86,6 +97,16 @@ braille: ⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖ } ``` +#### ⚠️ 분수는 무조건 LaTeX `\frac{}{}` 표기 (NON-NEGOTIABLE) + +수식의 **분수는 반드시 LaTeX `\frac{numerator}{denominator}` 형식만 사용**한다. `/`(슬래시)는 분수 표기와 별개의 표현이며 두 가지를 혼용하지 않는다. + +- ✅ `$\frac{e^x-e^{-x}}{2}$` — 분수 +- ❌ `(e^x-e^{-x})/2` — 슬래시(분수 아님) +- ❌ `$(e^x-e^{-x})/2$` — LaTeX 안의 슬래시도 분수 아님 + +`/`는 단순 슬래시 기호 점역으로 처리되며, 분수의 의미를 가지려면 `\frac{}{}`로 명시해야 한다. testcase 작성 시 분수 의미가 있는 모든 표현을 LaTeX로 통일한다. (수학 분수는 한국 점자 점역 시 분모를 분자보다 먼저 점역하므로 `\frac{a}{b}` → `b/a` 점역 결과가 나온다.) + 주요 LaTeX 변환: | 수식 | LaTeX | @@ -104,3 +125,140 @@ braille: ⠀⠁⠂⠃⠄⠅⠆⠇⠈⠉⠊⠋⠌⠍⠎⠏⠐⠑⠒⠓⠔⠕⠖ ### 대문자 수학 변수 수학 점자에서 대문자 변수(A, B, N 등)를 사용하는 internal은 기본 64셀 패턴에 포함되지 않는다. 이런 엔트리는 `expected`/`unicode`가 빈 문자열이며, 무결성 테스트에서 자동으로 skip된다. + +## Rust 테스트 작성 가이드 + +> 세부 규칙은 `libs/braillify/AGENTS.md#test-organization-non-negotiable` 참조. 아래는 모든 Rust 코드에 공통 적용되는 원칙이다. + +### 테스트 파일 배치 (NON-NEGOTIABLE) + +테스트 코드는 다음 우선순위로 배치한다: + +1. **inline `#[cfg(test)] mod tests { ... }`** — 검증 대상 `.rs` 파일 하단에 직접 작성 (기본값) +2. **owning module 안의 inline `#[cfg(test)] mod { ... }`** — 여러 모듈이 공유하는 테스트 utility 는 가장 가까운 공통 부모 모듈 (보통 `lib.rs`) 에 inline 블록으로 둔다 +3. **`tests/` 폴더 (integration test)** — 위 두 가지 모두 불가능한 경우 (예: 공개 API 만 사용하는 시나리오 테스트) + +**금지:** + +- ❌ `src/` 트리 내 **test 전용 standalone `.rs` 파일** (`src/test_helpers.rs`, `src/foo_test.rs` 등) +- ❌ production code 와 같은 파일에 `#[cfg(test)]` 가드 없이 두는 테스트 fixture + +### 파라미터화 테스트는 `rstest` 우선 (NON-NEGOTIABLE) + +같은 호출 shape (동일 함수 호출, 입력/기대값만 다름) 으로 **3개 이상**의 케이스가 모이면 **반드시 `rstest::rstest`** 로 변환한다. + +```rust +// ✅ 권장 +#[rstest::rstest] +#[case::one('1', '⠁')] +#[case::zero('0', '⠚')] +#[case::nine('9', '⠊')] +fn encodes_digits(#[case] ch: char, #[case] expected: char) { + assert_eq!(encode_digit(ch).unwrap(), decode_unicode(expected)); +} + +// ❌ for-loop 테이블 패턴은 새로 추가하지 않는다 +#[test] +fn encodes_digits_BAD() { + for (ch, expected) in [('1', '⠁'), ('0', '⠚'), ('9', '⠊')] { + assert_eq!(encode_digit(ch).unwrap(), decode_unicode(expected)); + } +} +``` + +**원칙:** + +- `#[case::label(...)]` 의 label 은 의미를 담는다 (`#[case::lower_a]`, `#[case::overflow_max]` 등) — 실패 메시지에서 즉시 케이스 식별 가능 +- 단일 입력만 다른 경우 `#[values(...)]` 사용 가능 (`fn t(#[values('a', 'b')] c: char)`) +- assertion 없는 smoke test 는 변환 의무 없음 — for-loop 가 더 간결하면 유지 +- 기존 테스트를 수정할 때 3+ assertion 패턴을 발견하면 **그 자리에서 rstest 로 마이그레이션** 한다 + +## 구현 원칙 + +### 일반화 필수, 꼼수 금지 (NON-NEGOTIABLE) + +변환 로직은 **PDF 규정에 근거한 일반 알고리즘**으로 작성한다. 테스트 통과가 목적이 아니라, **모든 변형 입력을 규정대로 변환하는 것**이 목적이다. + +- 테스트 케이스는 가능한 입력의 작은 부분집합일 뿐이다 +- 알고리즘이 옳다면 테스트는 자연히 통과한다 +- "테스트와 결과가 다르니 코드를 맞춘다"가 아니라, **테스트와 결과가 다르면 알고리즘 또는 테스트 둘 중 하나가 틀린 것이다** +- 테스트에 없는 새로운 입력이 들어와도 동일한 알고리즘으로 정확히 처리되어야 한다 + +### 금지된 꼼수 (BLOCKING — 발견 즉시 재작성) + +#### 1. 입력 → 출력 직접 매핑 + +```rust +// 금지 +if input == "안녕하세요" { return "⠁⠉⠊..."; } + +match input { + "안녕" => "...", + "학교" => "...", + _ => fallback(), +} +``` + +#### 2. 테스트 케이스 룩업 테이블 + +```rust +// 금지 — 테스트 입력/출력을 그대로 박아넣은 것 +const KNOWN: &[(&str, &str)] = &[ + ("안녕", "⠁⠉..."), + ("학교", "⠚⠁..."), +]; +``` + +#### 3. expected 역산 + +테스트 JSON의 `expected`/`unicode` 값을 보고 **그 값이 나오도록 코드를 작성하는 것**. 알고리즘은 오직 `docs/2024 개정 한국 점자 규정.pdf`의 규정에서만 도출한다. + +#### 4. 테스트 파일 의존 + +변환 로직이 `test_cases/` 경로의 파일을 읽거나 import하거나 참조하는 코드 일체. 테스트 데이터는 검증 단계에서만 쓰인다. + +#### 5. 케이스별 분기 폭증 + +같은 종류의 처리를 입력 단위마다 if/else 또는 match로 늘어놓는 것. 같은 규정이 적용되는 입력은 **하나의 일반 함수**로 처리한다. + +```rust +// 금지 — 음절별로 결과를 박아넣는 패턴 +fn convert_syllable(s: &str) -> &str { + match s { + "각" => "⠊⠁⠁", + "간" => "⠊⠁⠉", + "갈" => "⠊⠁⠂", + // ... 수천 줄 + } +} + +// 올바름 — 초성/중성/종성 분해 후 규정대로 조합 +fn convert_syllable(s: char) -> Vec { + let (cho, jung, jong) = decompose_hangul(s); + let mut out = vec![]; + out.extend(cho_to_braille(cho)); + out.extend(jung_to_braille(jung)); + if let Some(j) = jong { out.extend(jong_to_braille(j)); } + out +} +``` + +> **예외:** 단일 자모/기호의 점형 정의(예: ㄱ → ⠈, 숫자 표시 → ⠼)는 PDF가 명시한 기본 매핑이므로 허용된다. **음절/단어/구절 단위의 매핑은 모두 금지.** + +### 올바른 구현 방향 + +1. **PDF 규정 → 알고리즘** — 각 항(제N항)을 함수로 분리하고, 함수 doc에 근거 항 번호를 명시한다 +2. **계층 분해** — 자모 → 음절 → 단어 → 문장 순으로 단계화하여 각 층은 자기 책임만 진다 +3. **테스트는 검증 도구** — 알고리즘이 PDF 규정과 일치하는지 확인하는 용도이지, 코드가 맞춰야 할 정답표가 아니다 +4. **테스트 추가 시 코드 수정 불필요** — 같은 규정에 속하는 새 예제는 이미 알고리즘이 처리하고 있어야 한다. 새 예제 추가만으로 코드 변경이 필요하다면 알고리즘이 일반화되지 않은 것이다 + +### 자가 검증 체크리스트 + +PR/커밋 전 다음을 모두 확인한다: + +- [ ] 변환 로직 안에 `test_cases/` 경로 문자열이 없다 +- [ ] 테스트의 `input` 문자열이 코드에 리터럴로 등장하지 않는다 (단일 자모/기호 제외) +- [ ] 테스트의 `expected`/`unicode` 문자열이 코드에 리터럴로 등장하지 않는다 +- [ ] 같은 규정의 새 예제를 추가해도 코드 수정 없이 통과한다 +- [ ] 음절/단어 단위 분기가 자모 단위 일반 함수로 통합되어 있다 +- [ ] 모든 분기와 매핑은 PDF의 특정 항을 근거로 추적 가능하다 diff --git a/Cargo.lock b/Cargo.lock index 8f27dc08..7aa26147 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aho-corasick" version = "1.1.4" @@ -11,11 +26,26 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloca" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "anstream" -version = "0.6.21" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" dependencies = [ "anstyle", "anstyle-parse", @@ -28,15 +58,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" dependencies = [ "utf8parse", ] @@ -63,15 +93,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "assert_cmd" -version = "2.1.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcbb6924530aa9e0432442af08bbcafdad182db80d2e560da42a6d442535bf85" +checksum = "2aa3a22042e45de04255c7bf3626e239f450200fd0493c1e382263544b20aea6" dependencies = [ "anstyle", "bstr", @@ -95,9 +125,24 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] [[package]] name = "bit-set" @@ -116,9 +161,9 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" -version = "2.11.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" [[package]] name = "braillify" @@ -127,13 +172,17 @@ dependencies = [ "anyhow", "assert_cmd", "clap", + "criterion", + "dhat", "embed-manifest", "escargot", + "insta", "once_cell", "phf", "predicates", "proptest", "regex", + "rstest", "rustyline", "serde_json", "unicode-normalization", @@ -152,9 +201,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "cast" @@ -164,9 +213,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.56" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "shlex", @@ -184,11 +233,38 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "clap" -version = "4.5.53" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" dependencies = [ "clap_builder", "clap_derive", @@ -196,9 +272,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstream", "anstyle", @@ -208,9 +284,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" dependencies = [ "heck", "proc-macro2", @@ -220,9 +296,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "clipboard-win" @@ -235,9 +311,20 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + +[[package]] +name = "console" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +dependencies = [ + "encode_unicode", + "libc", + "windows-sys", +] [[package]] name = "console_error_panic_hook" @@ -249,6 +336,88 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "criterion" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "950046b2aa2492f9a536f5f4f9a3de7b9e2476e575e05bd6c333371add4d98f3" +dependencies = [ + "alloca", + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "itertools", + "num-traits", + "oorandom", + "page_size", + "plotters", + "rayon", + "regex", + "serde", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d80a2f4f5b554395e47b5d8305bc3d27813bacb73493eb1001e8f76dae29ea" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "dhat" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cd11d84628e233de0ce467de10b8633f4ddaecafadefc86e13b84b8739b827" +dependencies = [ + "backtrace", + "lazy_static", + "mintex", + "parking_lot", + "rustc-hash", + "serde", + "serde_json", + "thousands", +] + [[package]] name = "difflib" version = "0.4.0" @@ -262,12 +431,24 @@ dependencies = [ "braillify", ] +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + [[package]] name = "embed-manifest" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94cdc65b1cf9e871453ce2f86f5aaec24ff2eaa36a1fa3e02e441dddc3613b99" +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "endian-type" version = "0.2.0" @@ -309,9 +490,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "find-msvc-tools" @@ -346,12 +527,29 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-task" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +[[package]] +name = "futures-timer" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" + [[package]] name = "futures-util" version = "0.3.32" @@ -359,6 +557,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-core", + "futures-macro", "futures-task", "pin-project-lite", "slab", @@ -389,6 +588,29 @@ dependencies = [ "wasip3", ] +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + [[package]] name = "hashbrown" version = "0.15.5" @@ -400,9 +622,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -427,33 +649,54 @@ checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "indexmap" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.16.1", + "hashbrown 0.17.1", "serde", "serde_core", ] +[[package]] +name = "insta" +version = "1.47.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4a6248eb93a4401ed2f37dfe8ea592d3cf05b7cf4f8efa867b6895af7e094e" +dependencies = [ + "console", + "once_cell", + "similar", + "tempfile", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.94" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ "cfg-if", "futures-util", @@ -461,6 +704,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "leb128fmt" version = "0.1.0" @@ -469,9 +718,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.183" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libm" @@ -485,11 +734,20 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" [[package]] name = "memchr" @@ -507,6 +765,21 @@ dependencies = [ "walkdir", ] +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mintex" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c505b3e17ed6b70a7ed2e67fbb2c560ee327353556120d6e72f5232b6880d536" + [[package]] name = "nibble_vec" version = "0.1.0" @@ -518,9 +791,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.31.2" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ "bitflags", "cfg-if", @@ -563,6 +836,15 @@ dependencies = [ "libm", ] +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -581,6 +863,39 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + [[package]] name = "phf" version = "0.13.1" @@ -630,6 +945,34 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + [[package]] name = "portable-atomic" version = "1.13.1" @@ -647,9 +990,9 @@ dependencies = [ [[package]] name = "predicates" -version = "3.1.3" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" +checksum = "ada8f2932f28a27ee7b70dd6c1c39ea0675c55a36879ab92f3a715eaa1e63cfe" dependencies = [ "anstyle", "difflib", @@ -661,15 +1004,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" +checksum = "cad38746f3166b4031b1a0d39ad9f954dd291e7854fcc0eed52ee41a0b50d144" [[package]] name = "predicates-tree" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" +checksum = "d0de1b847b39c8131db0467e9df1ff60e6d0562ab8e9a16e568ad0fdb372e2f2" dependencies = [ "predicates-core", "termtree", @@ -685,6 +1028,15 @@ dependencies = [ "syn", ] +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.106" @@ -818,9 +1170,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha", "rand_core", @@ -854,11 +1206,40 @@ dependencies = [ "rand_core", ] +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + [[package]] name = "regex" -version = "1.12.2" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -868,9 +1249,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -883,6 +1264,62 @@ version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "rstest" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5a3193c063baaa2a95a33f03035c8a72b83d97a54916055ba22d35ed3839d49" +dependencies = [ + "futures-timer", + "futures-util", + "rstest_macros", +] + +[[package]] +name = "rstest_macros" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c845311f0ff7951c5506121a9ad75aec44d083c31583b2ea5a30bcb0b0abba0" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn", + "unicode-ident", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "1.1.4" @@ -944,11 +1381,17 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" @@ -982,9 +1425,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -999,11 +1442,17 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "slab" @@ -1059,11 +1508,27 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" +[[package]] +name = "thousands" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -1074,6 +1539,36 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.25.11+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +dependencies = [ + "indexmap", + "toml_datetime", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow", +] + [[package]] name = "unarray" version = "0.1.4" @@ -1097,9 +1592,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-width" @@ -1140,11 +1635,11 @@ dependencies = [ [[package]] name = "wasip2" -version = "1.0.2+wasi-0.2.9" +version = "1.0.3+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.57.1", ] [[package]] @@ -1153,14 +1648,14 @@ version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ - "wit-bindgen", + "wit-bindgen 0.51.0", ] [[package]] name = "wasm-bindgen" -version = "0.2.117" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -1171,9 +1666,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.67" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03623de6905b7206edd0a75f69f747f134b7f0a2323392d664448bf2d3c5d87e" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ "js-sys", "wasm-bindgen", @@ -1181,9 +1676,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.117" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1191,9 +1686,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.117" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -1204,18 +1699,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.117" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-bindgen-test" -version = "0.3.67" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941c102b3f0c15b6d72a53205e09e6646aafcf2991e18412cc331dbac1806bc0" +checksum = "74fde991ccdc895cb7fbaa14b137d62af74d9011be67b71c694bfc40edd3119c" dependencies = [ "async-trait", "cast", @@ -1235,9 +1730,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.67" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26bd6570f39bb1440fd8f01b63461faaf2a3f6078a508e4e54efa99363108d2" +checksum = "e925354648d2a4d1bf205412e36d520a800280622eef4719678d268e5d40e978" dependencies = [ "proc-macro2", "quote", @@ -1246,9 +1741,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-shared" -version = "0.2.117" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c29582b14d5bf030b02fa232b9b57faf2afc322d2c61964dd80bad02bf76207" +checksum = "684365b586a9a6256c1cc3544eee8680de48d6041142f581776ec7b139622ae9" [[package]] name = "wasm-encoder" @@ -1284,6 +1779,32 @@ dependencies = [ "semver", ] +[[package]] +name = "web-sys" +version = "0.3.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.11" @@ -1293,6 +1814,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-link" version = "0.2.1" @@ -1308,6 +1835,15 @@ dependencies = [ "windows-link", ] +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + [[package]] name = "wit-bindgen" version = "0.51.0" @@ -1317,6 +1853,12 @@ dependencies = [ "wit-bindgen-rust-macro", ] +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + [[package]] name = "wit-bindgen-core" version = "0.51.0" @@ -1398,18 +1940,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.42" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.42" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 0cba77ab..78509576 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,23 @@ resolver = "3" [workspace.package] version = "0.1.0" edition = "2024" +rust-version = "1.95" +# Native release: prioritize runtime speed. +# WASM builds override this profile in packages/node/Cargo.toml to keep size optimization. [profile.release] -opt-level = "s" +opt-level = 3 +lto = "thin" +codegen-units = 1 +strip = "symbols" +debug = 1 # required by dhat heap profiling for backtraces + +# WASM-targeted size-optimized release profile. +# Use via: cargo build --release --profile wasm-release -p node --target wasm32-unknown-unknown +[profile.wasm-release] +inherits = "release" +opt-level = "z" +lto = "fat" +codegen-units = 1 +strip = "symbols" +debug = false diff --git a/apps/landing/eslint.config.mjs b/apps/landing/eslint.config.mjs deleted file mode 100644 index c9f97135..00000000 --- a/apps/landing/eslint.config.mjs +++ /dev/null @@ -1,3 +0,0 @@ -import { configs } from 'eslint-plugin-devup' - -export default configs.recommended diff --git a/apps/landing/package.json b/apps/landing/package.json index 748e85ea..75e854e1 100644 --- a/apps/landing/package.json +++ b/apps/landing/package.json @@ -5,27 +5,25 @@ "scripts": { "dev": "next dev", "build": "next build", - "start": "next start", - "lint": "next lint" + "start": "next start" }, "dependencies": { - "@devup-ui/components": "^0.1.44", - "@devup-ui/react": "^1.0.35", + "@devup-ui/components": "^0.1.46", + "@devup-ui/react": "^1.0.37", "@mdx-js/loader": "^3.1.1", "@mdx-js/react": "^3.1.1", - "@next/mdx": "^16.2.2", + "@next/mdx": "^16.2.6", "@types/mdx": "^2.0.13", "braillify": "workspace:*", "clsx": "^2.1.1", - "katex": "^0.16.45", - "next": "16.2.4", - "react": "^19.2.4", - "react-dom": "^19.2.4", - "react-latex-next": "^3.0.0", + "katex": "^0.17.0", + "next": "16.2.6", + "react": "^19.2.6", + "react-dom": "^19.2.6", "react-syntax-highlighter": "16.1.1" }, "devDependencies": { - "@devup-ui/next-plugin": "^1.0.74", + "@devup-ui/next-plugin": "^1.0.77", "@types/node": "^25", "@types/react": "^19", "@types/react-dom": "^19", @@ -33,4 +31,4 @@ "babel-plugin-react-compiler": "^1.0.0", "typescript": "^6" } -} \ No newline at end of file +} diff --git a/apps/landing/src/app/docs/RightIndex.tsx b/apps/landing/src/app/docs/RightIndex.tsx index f4ce54a8..58e75adf 100644 --- a/apps/landing/src/app/docs/RightIndex.tsx +++ b/apps/landing/src/app/docs/RightIndex.tsx @@ -19,10 +19,10 @@ function IndexMenu({ {selected && } diff --git a/apps/landing/src/components/Header/Pages.tsx b/apps/landing/src/components/Header/Pages.tsx index dfebe190..350019b1 100644 --- a/apps/landing/src/components/Header/Pages.tsx +++ b/apps/landing/src/components/Header/Pages.tsx @@ -30,7 +30,7 @@ export default function Pages({ isIntersecting }: { isIntersecting: boolean }) { href="/docs/overview" > -
+
-
+
-
+
-