github.com/OrelSokolov/rqrcode.cr
0.1.0 / published Oct 12, 2026 / repository
Порт rqrcode 2.2.0 + rqrcode_core 1.2.0 (github.com/whitesmith/rqrcode) на Crystal — 1:1 API. Генерация QR-кодов (numeric/alphanumeric/byte_8bit, мульти-сегменты, уровни коррекции L/M/Q/H, версии 1–40) и рендереры: as_html / as_svg (rect + path) / as_ansi / as_png (чистый Crystal, без внешних зависимостей — встроенный мини-PNG вместо chunky_png).
rqrcode.cr
A 1:1 Crystal port of whitesmith/rqrcode 2.2.0 (+ the core of rqrcode_core 1.2.0) — QR code encoding and rendering to HTML/ANSI/SVG/PNG. Suite: 83 examples, 0 failures; the oracle replays matrices, errors and render output recorded from the real gems, 1:1.
Installation
dependencies:
rqrcode_cr:
github: OrelSokolov/rqrcode.cr
shards install
No external dependencies (the PNG renderer replaces chunky_png, see below).
Usage
require "rqrcode_cr"
qr = RQRCode::QRCode.new("https://example.com")
qr.as_html
qr.as_ansi(dark: "█", light: " ")
qr.as_svg(module_size: 6, use_path: true)
qr.as_png(size: 240, border_modules: 4) # => PNG blob
qr.checked?(0, 0)
qr.modules
# multi-segment input
core = RQRCodeCore::QRCode.new([
{data: "123", mode: :number},
{data: "abc", mode: :byte_8bit},
])
Feature comparison vs rqrcode 2.2.0 / rqrcode_core 1.2.0
Encoding (rqrcode_core)
| Feature | Original (rqrcode_core) | Port (rqrcode.cr) | Status |
|---|---|---|---|
QRCode.new(data, level:, size:, max_size:, mode:) — String, QRSegment or segment array | ✅ | Same | ✅ |
Modes :number / :alphanumeric / :byte_8bit (auto-detect) | ✅ | Same | ✅ |
Error-correction levels :l/:m/:q/:h (default :h), versions 1–40, auto version selection | ✅ | Same | ✅ |
| Multi-segment UTF-8 input | ✅ | Same | ✅ |
checked?(row, col) (+ deprecated dark?), modules, module_count, version, mode, error_correction_level, multi_segment?, inspect, to_s(dark:, light:, quiet_zone_size:) | ✅ | Same | ✅ |
Errors: QRCodeArgumentError (< ArgumentError), QRCodeRunTimeError — same messages | ✅ | Same | ✅ |
Non-string scalar data (CORE.new(123)) | raises QRCodeArgumentError | Compile-time error in Crystal (case excluded from the oracle) | ❌ (equivalent: compile-time check) |
Rendering (rqrcode)
| Feature | Original | Port | Status |
|---|---|---|---|
as_html | ✅ | Same | ✅ |
as_ansi(light:, dark:, fill_character:, quiet_zone_size:) | ✅ | Same | ✅ |
as_svg(fill:, color:, offset:, module_size:, shape_rendering:, standalone:, use_path:, viewbox:, svg_attributes:) — rect and path variants | ✅ | Same | ✅ |
as_png(size:, border_modules:, module_px_size:, border:, resize_exactly_to:, resize_gte_to:, fill:, color:, file:) — both sizing algorithms (exactly / gte) with exact pixel geometry | ✅ | Same | 🔶 |
PNG colors "black"/"white", hex 3/6, [r,g,b]/[r,g,b,a] | ✅ | Same | ✅ |
| PNG color_mode/bit_depth/interlace/compression options | ✅ | Accepted but ignored | 🔶 |
Quirks preserved intentionally (oracle-confirmed)
as_png(..., border:)is effectively ignored (border_moduleswins).- Integer division in
demerit_points_4. get_maskcompares>instead of>=.
Deviations & Crystal-specific notes
- Options are named arguments instead of Ruby trailing-hash
(
extract_options!→def to_s(dark = "x", ...));as_pngkeeps**optionsbecause the "passed or not" distinction selects the sizing algorithm. Int#between?is a monkeypatch (Ruby builtin, absent from the Crystal stdlib).- The unreachable
:mode_multibranch ofQRSegmentin the writer is omitted.
PNG without chunky_png
RQRCode::Export::PNG::Image is a minimal chunky_png replacement: an
RGBA canvas with new/[]=/save/to_s/resize/width/height.
Resize is an exact port of chunky_png's resample_nearest_neighbor
(Bresenham error accumulation, not floor scaling). The encoder writes
8-bit grayscale (chunky_png writes 1-bit — files are larger but valid,
verified with the ChunkyPNG decoder). CRC32 is a built-in table (not
exported by the Crystal stdlib).
Testing
ruby oracle/cases.rb > oracle/expected.yml # re-record against the real gems
crystal spec # 83 examples
spec/oracle_spec.cr— 57 cases recorded from the real gems: matrices (v1–v40, all L/M/Q/H levels, all modes, multi-segment, UTF-8), errors (class + message), HTML/ANSI/SVG (rect + path)/PNG (pixel geometry of both sizing algorithms + resize).spec/rqrcode_spec.cr— 26 unit tests on the API (QRMath, QRUtil, RS blocks, QRSegment, buffer, renderers), ported from README/API scenarios (the originals ship no test files in the gem package).
API
- Int
Ruby builtin, отсутствующий в Crystal stdlib
- RQRCode
- RQRCodeCore