# Poking the code
## Build and check
Use Rust 1.99.1, edition 2024. `rust-toolchain.toml` pins it, CI uses it, and
rustup will pick it up. A distro install of the same version works too.
From a checkout, try the CLI or install your local build:
```sh
cargo run -- parse examples/keep-a-changelog.md
cargo install --path . --locked
```
Then run the checks:
```sh
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo build --all-features
cargo test --all-features
cargo test --doc
cargo run -- validate --strict
cargo doc --no-deps
```
`bacon clippy` is handy while editing. `cargo nextest run --all-features` also
works. CI runs the required checks and uses nextest when it's installed.
It also builds the packaged crate with `cargo package --locked --all-features`.
The fixtures include normal changelogs and things a changelog probably shouldn't do.
## CI packages
After the checks pass, CI tests and builds on Windows x64 and Linux x64/ARM64.
Linux uses native runners with musl and verifies that the ELF has no interpreter
or shared-library dependencies. Both package payloads must match the built binary.
Windows links the C runtime statically and tests MSI installation, PATH changes,
and removal.
The package recipes live in [`.github/packaging/`](https://github.com/Katze719/logloom/tree/main/.github/packaging), with
scripts in [`.github/scripts/`](https://github.com/Katze719/logloom/tree/main/.github/scripts). nFPM 2.48.0 produces DEB/RPM
packages; downloads are checked against pinned SHA-256 hashes. Windows uses the
WiX 3 tools included in `windows-2022`. MSI builds currently require a plain
`major.minor.patch` version in `Cargo.toml`.
Artifacts and [installation examples](installation.md) are available per workflow
run. CI uploads artifacts; it doesn't create GitHub releases or publish packages.
For crates.io metadata, package contents, and upload checks, see
[publishing](publishing.md).
## Where things live
| [`src/lib.rs`](../src/lib.rs) | Public in-memory parsing API and format dispatch |
| [`src/model.rs`](../src/model.rs) | Owned, format-independent, Serde-compatible types |
| [`src/error.rs`](../src/error.rs) | Typed parsing failures |
| [`src/detection.rs`](../src/detection.rs) | Conservative format signatures and typed ambiguity errors |
| [`src/parsers/`](../src/parsers/) | Format implementations |
| [`src/parsers/markdown.rs`](../src/parsers/markdown.rs) | Shared Markdown blocks, links, and nesting limits |
| [`src/validation.rs`](../src/validation.rs) | Convention checks, separate from parsing |
| [`src/cli.rs`](../src/cli.rs) | Argument parsing, I/O, and exit codes; uses the public API |
| [`src/cli/help.rs`](../src/cli/help.rs) | Help examples and format lists generated from the CLI's enums |
| [`src/cli/render.rs`](../src/cli/render.rs) | Output formats and the buffered export limit |
| [`src/cli/render/`](../src/cli/render/) | Readable text/Markdown and CSV views |
| [`src/diagnostics.rs`](../src/diagnostics.rs) | Source annotations and colors |
| [`src/diagnostics/`](../src/diagnostics/) | Format-specific correction hints |
## Why these bits
| One Cargo package, library and binary | Shared parser without workspace overhead |
| pulldown-cmark events | CommonMark, source offsets, and reference resolution without recursive AST traversal; comrak's richer AST was unnecessary |
| clap derive, Serde, serde_json | CLI arguments, JSON, and JSONL |
| yaml_serde, toml, csv | Format-specific serialization and quoting; YAML uses the [YAML organization's maintained fork](https://github.com/yaml/yaml-serde) |
| annotate-snippets | Source diagnostics directly; color-eyre was unnecessary |
| Small calendar check | No chrono/jiff dependency needed for date-only validation |
| Flat Changesets mapping reader | Supports the fragment mapping subset; rejects unsupported YAML instead of evaluating aliases or templates |
## Add a format
1. Add it to `Format` and the CLI. Parse into the existing model and store the format for validation. Add conservative detection signatures and ambiguity tests.
2. Give it useful error hints and a file in `examples/`.
3. Test the normal input, the weird input, and the broken input through the API and CLI.
4. Write down the syntax and limits, link the example from the README, and run the checks above.
[Cargo.toml](../Cargo.toml) and [clippy.toml](../clippy.toml) enforce the
[Namtao Rust guidelines](https://www.namtao.com/rust/).
Clippy is picky on purpose: fix the code when it complains.
Keep production code free of panics and unsafe code, and keep the lint settings strict.