# Changelog

## [1.2.0] - 2026-07-01

### Added

- **Batch encoding**: `QrCode::batch(inputs, ec_level) -> QrResult<Vec<QrCode>>` — encodes many inputs at once, short-circuiting on the first error (no new deps; ~32ms/1000 short codes).
- **Style templates**: `QrTemplate` (serde-derivable: dark/light hex colors, module size, quiet zone) with presets (`minimal`, `dark_mode`, `high_contrast`, `corporate`), applied via `Renderer::template` for `StyledPixel` backends.
- `render::StyledPixel` trait (`from_hex`) implemented for the image RGB/RGBA, EPS, PDF, and ANSI backends.
- `examples/batch_template.rs`.

### Notes / deferred

- `par_batch` (rayon), batch render-to-files / grid / packaging, streaming / CSV / JSON data sources, brand customization (logo / captions / color-scheme), and template inheritance / TOML-YAML loading are deferred (external crates / image-heavy / couple to deferred features).
- Templates don't cover the borrowing `svg`/`html` backends (their color borrows the input) — apply those colors manually.

## [1.1.0] - 2026-07-01

### Added

- **Serde serialization** (opt-in `serde` feature): `Serialize`/`Deserialize` on `Color`, `EcLevel`, `Version`, `Mode`, `QrError`, and `Info`, plus a `QrCodeData` wrapper with `QrCode::to_serializable()` / `from_serializable()`. JSON round-trip tested (`tests/serde.rs`).
- **`no_std` + `alloc` support**: a default-on `std` feature; with it disabled the library builds as `#![no_std]` + `alloc` (`cargo build --no-default-features --features svg`). The `image` and `cli` features imply `std`.

### Changed

- Library internals use `core::` / `alloc::` instead of `std::` throughout (no behavior change for std users).

### Notes / deferred

- WASM bindings, framework integrations (Axum/Actix/Rocket/Leptos/Yew), interop with other QR crates, and GBK/Big5 charsets are deferred (separate companion crates / external infra / algorithmic work).

## [1.0.0] - 2026-07-01

🎉 **First stable release.** The public API is now frozen; future breaking
changes will require a new major version.

### Stable-release work

- **API freeze & full documentation**: every public item is now documented, and
  `#![deny(missing_docs)]` is enforced at the crate root so the standard holds
  going forward. `cargo doc --all-features` is warning/error-free.
- **`Info` is `#[non_exhaustive]`** — metadata fields may grow in 1.x without a
  breaking change (`QrError` was already `#[non_exhaustive]`).
- **MSRV declared**: `rust-version = "1.85"` (edition 2024).
- **`CONTRIBUTING.md`** added: dev setup, feature flags, the quality bar,
  commit conventions, and the release flow.
- **Packaging verified**: `cargo package` is clean.

### Notes / deferred (maintainer / external infrastructure)

- Stabilization items needing external tooling or credentials remain the
  maintainer's responsibility: `cargo-tarpaulin` coverage reporting,
  `cargo-fuzz` / `cargo miri`, cross-platform/WASM CI, the actual
  `cargo publish` to crates.io, and the GitHub Release.
- No behavioral change versus 0.6.0; this release codifies API stability.

## [0.6.0] - 2026-07-01

### Added

- Criterion benchmark suite (`benches/encoding.rs`, `benches/rendering.rs`; dev-dependency only — the library stays zero-dependency). Encoding: short/medium/long payloads + v1/v10/v20/v30/v40; rendering: string/svg/image/eps
- `QrCode::colors() -> &[Color]` — zero-copy borrow of the module slice (complements `to_colors()` / `into_colors()`)
- `Color` is now `#[repr(u8)]` with explicit discriminants (`Light = 0`, `Dark = 1`) — deterministic 1-byte layout, FFI-friendly, makes `Color as u8` sound
- Compile-time guarantee (and docs) that `QrCode: Send + Sync`

### Changed (Performance)

- `ec::create_error_correction_code` allocates its buffer once (`Vec::with_capacity`) instead of `to_vec()` + `resize()` realloc — bench: `encode/long` ~6.06ms → ~5.68ms (~6%), no regression elsewhere
- EPS renderer preallocates its output buffer (was the only renderer that didn't) — bench: `render/eps` ~15.5µs → ~14.7µs

### Notes

- Deferred (external deps conflict with zero-dependency): `SmallVec`, `bumpalo` arena, `rayon` parallel (a future `parallel` feature).
- Deferred (breaking/complex): 1-bit-per-module storage, `unsafe new_unchecked`, DP segmentation.
- Deferred (infra): CI bench regression detection, memory profiling, compile-time/monomorphization opts.

## [0.5.0] - 2026-07-01

### Added

- `QrCode::for_gs1(data)` — GS1 / FNC1-first-position convenience constructor (smallest fitting version, medium error correction)
- `QrCode::info() -> Info` metadata struct (version, ec_level, width, module_count, max_allowed_errors, data_capacity_bytes); backed by a new public `bits::data_capacity_bits(version, ec_level)`
- `QrCode::alt_text(data)` and `alt_text_custom(data, f)` — accessible alt-text generation (URL-aware: "linking to …" vs "containing: …")
- Builder `.force_mode(M)` (alias of `.encoding_mode(M)`) now works without a pinned version — auto-selects the smallest fitting version for the forced mode
- `render::svg::aria_label(svg, label)` and `render::html::aria_label(html, label)` — inject `role="img"` + `aria-label` for screen readers
- `render::html::inject_attributes(html, attrs)` — arbitrary attributes on the QR container (`<table>`/`<div>`)
- Examples: `encode_gs1`, `alt_text`, `accessible_svg`

### Fixed

- `render::svg::inject_attributes` now targets the `<svg>` root element instead of the `<?xml ?>` declaration (attributes were previously misplaced between the XML prolog and `<svg>`)

### Notes

- Deferred to later versions (need external decoder/scanner verification or a larger refactor): Structured Append (§1), custom Finder/Alignment patterns (§2), encoding stats (§4.2), and `Info` fields requiring input/mask retention (encoding_modes, mask_pattern, remaining_capacity)

## [0.4.0] - 2026-07-01

### Added

- `qrencodes` CLI: a full command-line generator behind the new opt-in `cli`
  feature (`clap`-based, zero-dependency library by default). Supports all
  output formats (`string`, `unicode`, `ansi`, `svg`, `png`, `eps`, `pic`,
  `html`, `pdf`), error-correction level, QR/Micro version, module size,
  quiet zone, `--dark`/`--light` colors, `--invert`, `--unicode-mode`, stdin
  input, and `--batch` (one QR per line)
- `QrCode::builder(data)` builder with `.ec_level()`, `.version()`, `.micro()`,
  `.encoding_mode()` and `.build()`, delegating to the existing encoders
- Convenience constructors: `QrCode::for_url`, `for_wifi`, `for_vcard`,
  `for_text`
- Module iterators: `QrCode::rows()` (yielding `Row`) and
  `QrCode::dark_modules()` (yielding `(x, y)` coordinates), zero-allocation
- `FromStr` implementations for `EcLevel`, `Version` (`1..=40`, `M1..M4`) and
  `Mode`, plus a public `EnumParseError` type
- New examples: `encode_kanji`, `encode_eci`, `encode_fnc1`, `custom_colors`,
  `error_handling`, `cli_tool`, `structured_append`
- `QrError` re-exported at the crate root

### Changed

- `QrError` is now `#[non_exhaustive]` and its variants carry structured,
  `Copy` context: `InvalidVersion { version, ec_level }`,
  `InvalidEciDesignator { value }`, `InvalidCharacter { position, byte }`.
  `Display` messages now include this context. (Variant shapes changed — a
  source-breaking change permitted at 0.x.)
- The `image` feature now enables the PNG codec (`image/png`) so that
  `encode_to_format(ImageFormat::Png)` and the CLI `-f png` actually work

### Fixed

- `render::colors` module doc example no longer requires the `svg` feature,
  so `cargo test --no-default-features` is clean

### Notes

- WASM playground and `validate` subcommand (roadmap §5) are deferred to their
  scheduled versions (v1.1.0 / v1.4.0); i18n error messages are deferred in
  favor of the enriched English `Display`

## [0.3.0] - 2026-06-11

### Added

- HTML table and CSS Grid renderer (`html` feature) with `Mode::Table` and `Mode::Grid` modes
- SVG `inject_attributes()` for adding custom attributes to the root `<svg>` element
- SVG `round_corners()` post-processing function for rounded module rendering
- SVG `animate()` post-processing function with `ScanLine`, `FadeIn`, `Pulse` presets
- `Dense2x2` Unicode renderer using quadrant block elements (U+2596–U+259F) for 2×2 pixel packing
- `Dense3x2` Unicode renderer using sextant characters (U+1FB00–U+1FB3F) for 3×2 pixel packing
- `Braille` Unicode renderer using Braille characters (U+2800–U+28FF) for 2×4 pixel packing
- ANSI TrueColor terminal renderer (`ansi` module) with 24-bit color and color-change optimization
- PDF vector renderer (`pdf` feature) with direct PDF generation, no external dependencies
- `render::colors` module with hex/RGB/RGBA/CSS color conversion utilities
- `Srgba` unified color type with hex/CSS/ANSI/EPS-PDF conversions and `lerp()` interpolation
- `overlay_logo()` function for embedding logos into QR code images (alpha-blended, auto-resized)
- `encode_to_format()` function for encoding QR images to JPEG, WebP, BMP, TIFF, GIF formats
- `apply_gradient_background()` function with vertical/horizontal/diagonal gradient support
- Smart sizing presets: `for_web()`, `for_print(dpi)`, `for_social(platform)` on Renderer builder

### Changed

- SVG path optimization: merged horizontally adjacent rectangles into single path segments

## [0.2.1] - 2026-06-11

### Changed

- Excluded roadmap files from version control (kept locally only)
- Version bump to 0.2.1

## [0.2.0] - 2026-06-11

### Added

- EPS (Encapsulated PostScript) renderer (`eps` feature)
- PIC (troff) renderer (`pic` feature)
- `QrCode::new_micro()` and `QrCode::micro_with_error_correction_level()` for automatic Micro QR encoding
- `bits::encode_auto_micro()` for automatic Micro QR version selection
- `const fn` annotations on `QrCode::version()`, `QrCode::error_correction_level()`, `QrCode::width()`, `Version::width()`, `Bits::new()`
- Module-level documentation for bits, canvas, ec, optimize, render modules
- `docs/index.md` project documentation page
- Boundary tests: v40 encoding, M4 encoding, empty input, data-too-long, ECI designators, all versions
- Integration test suite in `tests/` directory

### Fixed

- Micro QR Version 3/L half codeword encoding bug (absorbed from upstream PR #90)
- Panic in `Bits::push_terminator` when padding calculation underflows (absorbed from upstream PR #91)

### Changed

- SVG output optimized with path commands for smaller file size (absorbed from upstream PR #74)
- Replaced `Box<dyn Fn>` heap allocation with stack closure in `compute_finder_penalty_score`
- Updated `rustfmt.toml` edition to 2024
- CI matrix: nightly + stable only, removed MSRV constraint

### Removed

- Deprecated methods: `QrCode::to_vec()`, `QrCode::into_vec()`, `Canvas::to_bools()`, `Renderer::module_size()`, `Renderer::min_width()`, `Renderer::to_image()`
- `bench` feature and all benchmark code (incompatible with stable Rust)
- `rust-version` field from Cargo.toml
- `Cargo.lock` entry from `.gitignore`
