{"id":50826418,"url":"https://github.com/mlund/xdms-rs","last_synced_at":"2026-06-13T19:34:38.780Z","repository":{"id":360147327,"uuid":"1248472804","full_name":"mlund/xdms-rs","owner":"mlund","description":"A pure-Rust, dependency-free library for unpacking DMS (Disk Masher System) Amiga disk archives into raw ADF disk images.","archived":false,"fork":false,"pushed_at":"2026-05-25T06:55:24.000Z","size":71,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-13T19:34:34.585Z","etag":null,"topics":["amiga","compression"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mlund.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-24T17:29:25.000Z","updated_at":"2026-05-25T06:54:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mlund/xdms-rs","commit_stats":null,"previous_names":["mlund/xdms-rs"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/mlund/xdms-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlund%2Fxdms-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlund%2Fxdms-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlund%2Fxdms-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlund%2Fxdms-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mlund","download_url":"https://codeload.github.com/mlund/xdms-rs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mlund%2Fxdms-rs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34298247,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-13T02:00:06.617Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amiga","compression"],"created_at":"2026-06-13T19:34:33.724Z","updated_at":"2026-06-13T19:34:38.771Z","avatar_url":"https://github.com/mlund.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# xdms-rs\n\nA pure-Rust, dependency-free library for unpacking **DMS** (Disk Masher System)\nAmiga disk archives into raw **ADF** disk images.\n\n## Origin\n\nA Rust port of **xDMS**, the portable public-domain DMS unpacker\nwritten by André Rodrigues de la Rocha and maintained by Heikki Orsila. DMS was\nthe de-facto Amiga standard for storing non-DOS disks (games, demos); emulators\nexpect ADF/ADZ instead. The original C decoder is the reference for this port.\n\n## Usage\n\n### Command-line tool\n\nPrebuilt binaries are on the [releases page](https://github.com/mlund/xdms-rs/releases).\nOr install from source using the [Rust toolchain](https://rustup.rs):\n\n```sh\ncargo install --git https://github.com/mlund/xdms-rs\n```\n\nThe `xdms-rs` binary partially mirrors the reference C version.\n\n```text\nxdms-rs u \u003cfile.dms\u003e [output.adf]   unpack to a raw ADF disk image (output defaults to \u003cfile\u003e.adf)\nxdms-rs t \u003cfile.dms\u003e                test archive integrity (CRCs and checksums)\nxdms-rs v \u003cfile.dms\u003e                view archive information\nxdms-rs f \u003cfile.dms\u003e                view full information (adds banner and FILEID.DIZ)\nxdms-rs d \u003cfile.dms\u003e                show attached FILEID.DIZ\nxdms-rs b \u003cfile.dms\u003e                show attached banner\n```\n\n### Rust API\n\n```rust,no_run\n// One-liner: decompress a .dms to a .adf\nxdms::unpack_file(\"disk.dms\", \"disk.adf\")?;\n\n// Or get the bytes directly\nlet adf: Vec\u003cu8\u003e = xdms::unpack_to_vec(std::io::stdin().lock())?;\n# Ok::\u003c(), xdms::Error\u003e(())\n```\n\n```rust,no_run\nuse xdms::DmsArchive;\n\n// Full control: metadata, password, salvage mode, custom sink\nlet mut archive = DmsArchive::open(\"disk.dms\")?.with_password(\"secret\");\nprintln!(\"{}\", archive.info());          // human-readable summary\nlet summary = archive.unpack_to(std::io::stdout().lock())?;\nprintln!(\"{} tracks\", summary.tracks);\n\n// Integrity check only (no output):\nDmsArchive::open(\"disk.dms\")?.verify()?;\n# Ok::\u003c(), xdms::Error\u003e(())\n```\n\nThe crate is `no_std` + `alloc` when built with `default-features = false`; the\n`std` feature (on by default) adds the `std::io` `Read`/`Write` API.\n\n\n## Test coverage\n\nAll seven compression modes are implemented. How each is verified:\n\n| Mode           | Coverage |\n| -------------- | -------- |\n| `NOCOMP`       | synthetic tests + the RLE fixture's banner/FILEID.DIZ tracks |\n| `SIMPLE (RLE)` | **byte-exact** committed fixture from the independent [adf2dms] encoder, plus round-trip unit tests |\n| `QUICK`        | round-trip unit test (literals + a match) |\n| `MEDIUM`       | round-trip unit test (literal path) |\n| `DEEP`         | faithful port — ⚠️ **no end-to-end fixture** (no public DMS sample uses this obsolete mode) |\n| `HEAVY1`       | **byte-exact** vs the reference C `xdms` on a real public-domain disk |\n| `HEAVY2`       | **byte-exact** vs the reference C `xdms` on a real public-domain disk |\n\nEncryption, banner / FILEID.DIZ capture, salvage mode, and header/CRC/checksum\nvalidation each have tests too.\n\nFixtures are external: the `HEAVY` disk images download on\ndemand (`cargo run --example fetch_fixtures`) into a gitignored directory and\ntheir tests skip when absent, while the tiny RLE archive is committed under\n`tests/data/`. \"Byte-exact\" means the decoded ADF's SHA-256 matches the reference\noutput. Run the suite with `cargo test`.\n\n[adf2dms]: https://github.com/dlitz/adf2dms\n\n## Design goals\n\nThe port was planned around a few deliberate choices:\n\n- **Deep modules, small surface.** A handful of types (`DmsArchive`, `Info`,\n  `Summary`, `Error`) and a few one-liner functions; every decompressor, bit\n  reader, Huffman table, and sliding window is hidden behind one `Decompressor`.\n- **Idiomatic, expressive Rust — not a C transliteration.** The C's magic\n  integers become enums/newtypes (`Mode`, `DiskType`, `GenInfo`, `TrackFlags`),\n  its `#define`s become named constants, and byte parsing/validation lives in\n  `From`/`TryFrom` impls. Names say what they mean (`packed_len`, not `pklen1`).\n- **Very few dependencies — in fact zero.** No runtime *or* dev dependencies;\n  CRC-16, the bit reader, the Huffman builders, and even the tests' SHA-256 are\n  implemented in-crate.\n- **`core`/`alloc`-first.** The engine uses only `core` and `alloc`; `std::io`\n  is confined behind a default `std` feature, so a `no_std` build is mechanical.\n- **Faithful and byte-exact.** Output is validated to match the reference C\n  `xdms` bit-for-bit; decode loops mirror the original algorithms closely.\n- **Test-driven, with an oracle.** Built red→green→refactor, using the original\n  C binary (and the independent `adf2dms` encoder) as golden references.\n- **Portable and linted.** Pure-Rust engine with no platform APIs; CI covers\n  Linux/macOS/Windows plus a `no_std` build, with Clippy's nursery lints on.\n- **Comments explain *why*, not *what***\n\nAssistance of Claude Opus 4.7 was used, adhering to the\n[LLVM AI tool use policy](https://llvm.org/docs/AIToolPolicy.html).\n\n\n## Performance\n\nPure decode throughput vs the reference C `xdms`, both decoding the same\npublic-domain disks to memory (Rust `--release`, C `-O2`, Apple arm64, startup\namortized over 2000 iterations). Output is byte-identical.\n\n| Disk (mode) | Rust | C | speedup |\n| --- | --- | --- | --- |\n| GoldenFleece (HEAVY2) | 1.29 ms · 699 MB/s | 1.64 ms · 550 MB/s | 1.27× |\n| Gory_Story (HEAVY1) | 4.04 ms · 223 MB/s | 4.71 ms · 191 MB/s | 1.17× |\n\n\n## License\n\nLicensed under either of [MIT](LICENSE-MIT) or [Apache-2.0](LICENSE-APACHE) at\nyour option.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlund%2Fxdms-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmlund%2Fxdms-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlund%2Fxdms-rs/lists"}