qrcode-rs 2.1.1

QR code encoder in Rust,Generate QR Code matrices and images in RAW, PNG and SVG formats.
Documentation
# Contributing to qrcode-rs

Thanks for your interest in improving `qrcode-rs`! This guide covers the
development setup, the quality bar every change must meet, and the commit/PR
conventions used in this repository.

## Getting started

- **Rust toolchain**: stable **1.85 or newer** (the crate uses edition 2024;
  declared via `rust-version` in `Cargo.toml`).
- **Build & test**:

  ```bash
  cargo build --all-features
  cargo test --all-features
  ```

## Project layout

```
src/
  lib.rs        # qrcode-rs facade: QrCode, builder, streams, re-exports
  bin/          # qrencodes CLI (behind the `cli` feature)
crates/
  qrcode-core/  # encoding core, traits, module views, plugin contracts
  qrcode-render/# shared render traits, text/unicode/ansi/image helpers
  qrcode-parse/ # WiFi/vCard/GS1 payload parsers
  qrcode-decode/# decoder traits, grayscale views, rqrr adapter, SA parser
  qrcode-*/     # individual backend crates: svg, eps, pic, html, pdf
benches/        # criterion benchmarks (encoding, rendering)
examples/       # runnable examples
tests/          # integration tests
docs/           # roadmap & planning (local; see below)
```

## Feature flags

The **library is zero-dependency by default** — the core encoder pulls in no
external crates. Optional capabilities are feature-gated:

| Feature   | Enables                                  |
|-----------|------------------------------------------|
| `image`   | PNG/JPEG/… rendering via the `image` crate (includes the PNG codec) |
| `svg`     | SVG renderer                             |
| `eps`     | Encapsulated PostScript renderer         |
| `pic`     | troff PIC renderer                       |
| `html`    | HTML table / CSS Grid renderer           |
| `pdf`     | vector PDF renderer (no external dep)    |
| `async`   | Tokio-backed async rendering helpers     |
| `decode-rqrr` | decoder adapter through `rqrr`        |
| `compat-1x` | transitional 1.x facade compatibility  |
| `cli`     | the `qrencodes` binary (`clap`-based)    |

`default = ["std", "image", "svg", "pic", "eps", "html", "pdf"]`. When adding
a new dependency, prefer a feature gate or a hand-written implementation to
honor the zero-dependency principle.

## Quality bar

Every PR must pass:

```bash
cargo test --workspace --all-features
cargo test --workspace --no-default-features
cargo test --test proptest --all-features
cargo test --test differential --all-features
cargo clippy --workspace --all-features --all-targets -- -D warnings
cargo fmt --all --check
cargo doc --all-features --no-deps        # warning/error-free (#![deny(missing_docs)] is enforced)
```

All public API must be documented (`#![deny(missing_docs)]` is set in
`src/lib.rs`). New features should include unit tests and/or doctests, and an
example where useful.

## Security-sensitive changes

Please read [SECURITY.md](SECURITY.md) before reporting or discussing a
vulnerability. Keep vulnerability details, credentials, personal data, and
production inputs out of public issues, pull requests, test fixtures, logs, and
fuzz corpora. Use GitHub Security Advisories for suspected vulnerabilities.

Changes that touch `unsafe`, CPU intrinsics, indexing, dimensions, parsers,
decoders, image allocation, or CLI input must include a short safety rationale
and focused boundary tests. SIMD code must retain feature guards, prove vector
loads are within the slice, and preserve a scalar fallback for unsupported
targets. Prefer checked arithmetic and typed errors at public boundaries over
panic-based validation.

When adding or upgrading a dependency, keep it feature-gated when practical,
explain why it is needed, review its transitive impact, and update
`Cargo.lock`. Run the repository's available advisory check before opening a
PR. New fuzz targets should accept arbitrary bytes without panicking and
should document any intentionally bounded input or resource budget.

## Property, differential, and fuzz testing

The v2 test architecture includes three layers beyond ordinary integration
tests:

```bash
cargo test --test proptest --all-features
cargo test --test proptest --no-default-features
cargo test --test differential --all-features
cargo test --test differential --no-default-features
```

The `fuzz/` workspace is a `cargo-fuzz` project with targets for core encoding,
fixed-version encoding, SVG rendering, structured payload parsing, and
structured append. Use a compile check for quick local validation:

```bash
cargo check --manifest-path fuzz/Cargo.toml --bins
```

For a short local fuzz smoke run, install `cargo-fuzz` and run a bounded target:

```bash
cargo install cargo-fuzz --locked
cargo fuzz run encode -- -runs=100
cargo fuzz run render_svg -- -runs=100
```

## Commit conventions

- Use **conventional-commit** prefixes: `feat:`, `fix:`, `perf:`, `docs:`,
  `refactor:`, `test:`, `style:`, `chore:`, optionally scoped
  (`feat(v0.5.0): …`).
- Make **small, focused commits** — one logical change each.
- End every commit message with exactly this trailer and no other
  `Co-Authored-By`:

  ```
  Co-Authored-By: heihutu <heihutu@gmail.com>
  ```

## Pull requests

1. Open a PR against `main` (this project develops on `main`).
2. Ensure the quality bar above is green.
3. Update `CHANGELOG.md` and, where relevant, the roadmap docs.
4. For breaking changes (only on a major-version bump), describe the migration
   path.

## Releases

Releases follow [SemVer](https://semver.org). The flow:

1. Update `version` in `Cargo.toml`.
   For a major workspace release, keep `qrcode-rs` and all publishable split
   crates on the same version and update every path dependency version
   constraint.
2. Add a `## [X.Y.Z]` section to `CHANGELOG.md` (group by Added / Changed /
   Fixed / Notes, list deferrals explicitly).
3. Update crate READMEs and the root README when a published crate boundary,
   feature flag, or install snippet changes.
4. Tick the relevant roadmap checklist (`docs/roadmap/v*.md`) and update
   `docs/roadmap.md` (current version + status).
5. Verify the quality bar, then check package file lists:

   ```bash
   cargo package --workspace --allow-dirty --no-verify --list
   ```

   A full `cargo package --workspace` before anything has been published will
   fail for crates that depend on newly split workspace crates, because Cargo
   resolves publishable path dependencies through the registry. Use the file-list
   check before publishing, then publish in dependency order.

6. Publish split crates before the facade, skip workspace-local crates such as
   `qrcode-compat`, and wait for each version to appear in the crates.io index
   before publishing crates that depend on it:

   ```bash
   version=2.1.0
   for crate in \
     qrcode-core qrcode-render qrcode-parse qrcode-decode \
     qrcode-svg qrcode-eps qrcode-pic qrcode-html qrcode-pdf qrcode-rs
   do
     cargo publish --registry crates-io --package "$crate"
     until cargo info "${crate}@${version}" --registry crates-io >/dev/null 2>&1
     do
       sleep 10
     done
     sleep 300
   done
   ```

## Roadmap & local docs

The roadmap lives in `docs/roadmap/`. Note that `docs/*` (except
`docs/images/` and `docs/index.md`) are **gitignored and kept locally** —
planning notes and per-version implementation plans live there and are not
version-controlled. Trust `Cargo.toml`'s `version` and `CHANGELOG.md` for the
true release state, not the roadmap status markers (which can lag).