The platform-independent Rust core of 一典 Onedict (README §1). Zero macOS/UI dependencies, so the same crate backs macOS today and Windows / iOS / Android / HarmonyOS later behind one UniFFI binding.
core/
├── Cargo.toml # workspace
└── crates/
├── onedict-core/ # the library
│ ├── src/
│ │ ├── mdict/ # MDX/MDD container parsing
│ │ │ ├── header.rs # UTF-16LE XML header; v1/v2; encoding
│ │ │ ├── decrypt.rs # RIPEMD-128 keyword-index de-obfuscation
│ │ │ ├── lzo.rs # pure-Rust LZO1X decompression
│ │ │ └── mod.rs # key/record sections, adler-verified blocks, 64MB LRU
│ │ ├── normalize.rs # NFKD + strip diacritics/case/punct
│ │ ├── lemmatize.rs # word-form reduction + irregular verbs
│ │ ├── index.rs # SQLite: prefix/wildcard/approximate lookup
│ │ ├── store.rs # favorites / history
│ │ ├── wiki.rs # Wikipedia REST client + 7-day cache
│ │ ├── server.rs # onedict:// resources + Shadow-DOM render shell
│ │ ├── library.rs # Library façade (import / suggest / lookup / …)
│ │ ├── ffi.rs # UniFFI surface (feature = "ffi")
│ │ └── lib.rs
│ └── tests/roundtrip.rs # synthetic-MDX end-to-end tests
└── onedict-cli/ # `onedict` validation CLI (M1)
cd core
cargo test # 32 tests: unit + full parse-matrix round trip
cargo clippy --all-targets # clean (0 warnings)
cargo build --release # optimized CLI + libThe default build is fully offline and lean. Two optional features:
| Feature | Pulls in | Enables |
|---|---|---|
net |
ureq |
live Wikipedia fetch (wiki.rs) |
ffi |
uniffi |
Swift↔Rust bindings + uniffi-bindgen bin |
onedict info dict.mdx # header metadata + entry count
onedict keys dict.mdx --limit 20 # list headwords / resource paths
onedict lookup dict.mdx serendipity # single-file exact lookup
onedict bench dict.mdx # parse + index-build timing
onedict import <data_dir> dict.mdx # register + build the SQLite index
onedict suggest <data_dir> seren # prefix / wildcard suggestions
onedict query <data_dir> serene # aggregated multi-dict lookup
onedict bench-query <data_dir> seren # warm-connection latency (median/p95)
onedict wiki <data_dir> Rust --lang en # (requires --features net)- Versions: v1 (4-byte ints) and v2 (8-byte ints, adler-32 block checks). v3 (MdxBuilder 4.x) is detected and rejected with a human message.
- Compression: none / zlib / LZO1X — all pure Rust, no C dependency.
- Encoding: UTF-8 / UTF-16LE / GBK / Big5.
- Encryption: keyword-index (
Encrypted="2", RIPEMD-128 scheme) supported; RegCode commercial encryption rejected with a human message. - Resources:
foo.mdd+foo.1.mdd,foo.2.mdd… auto-associated; case-insensitive, slash-agnostic path lookup. - Every decompressed block is adler-32 verified, so any decode error surfaces as a clean checksum message, never silent corruption.
Parsing is clean-room from public reverse-engineering docs — no GPL code
copied (README §1 / 技术方案 §11). onedict-core is intended to ship under
MIT/Apache-2.0.
| Metric | Result | Budget |
|---|---|---|
| Parse header + key index | 70 ms | — |
| Build SQLite index | 606 ms (→ 6.4 s / 100 MB) | ≤ 10 s / 100 MB ✓ |
| Import (on-disk index) | ~1.0 s | — |
| Warm prefix query | 2 µs – 950 µs | < 10 ms ✓ |
Prefix suggestion uses an index-friendly range predicate (normalized >= lo AND < hi) with a bounded candidate scan, served entirely from the covering
idx_norm index.