smart-package-tracker 0.2.0

Generate package tracking IDs and render them as Code 128 barcodes (PNG and SVG)
Documentation
//! Generate package tracking IDs and render them as barcodes.
//!
//! ```
//! # #[cfg(all(feature = "os-rng", feature = "code128", feature = "png", feature = "svg"))]
//! # fn main() -> Result<(), smart_package_tracker::Error> {
//! use smart_package_tracker::{Barcode, RenderOptions, TrackingId};
//!
//! // 1. Mint an identifier.
//! let id = TrackingId::generate()?;          // e.g. PKG-9ED9285C
//!
//! // 2. Encode it as a Code 128 barcode.
//! let barcode = Barcode::code128(&id)?;
//!
//! // 3. Export it.
//! let options = RenderOptions::default();    // 300 dpi, 13 mil, 25 mm tall
//! let png: Vec<u8> = barcode.to_png(&options)?;
//! let svg: String  = barcode.to_svg(&options)?;
//!
//! assert_eq!(&png[..8], b"\x89PNG\r\n\x1a\n");
//! assert!(svg.contains("<svg"));
//! # Ok(())
//! # }
//! # #[cfg(not(all(feature = "os-rng", feature = "code128", feature = "png", feature = "svg")))]
//! # fn main() {}
//! ```
//!
//! # Design
//!
//! The pipeline has two independent halves, joined by a dimension-agnostic bit
//! grid:
//!
//! ```text
//! TrackingId ──▶ Symbology::encode ──▶ Symbol ──▶ Renderer::render ──▶ bytes
//!                (Code 128 | QR)       (BitMatrix)  (Png | Svg)
//! ```
//!
//! A linear barcode is a one-row [`BitMatrix`](symbology::BitMatrix); a matrix
//! symbology such as QR is a square one. Because renderers consume the grid
//! rather than the symbology, adding a format means implementing
//! [`Symbology`](symbology::Symbology) and nothing else — QR support landed
//! without a single change to the PNG or SVG renderers.
//!
//! Both renderers share one [`Layout`](render::Layout) calculation, so PNG and
//! SVG output describe identical geometry at identical physical size.
//!
//! # Choosing an entropy width
//!
//! [`TrackingId::generate`] defaults to 32 bits of randomness — the familiar
//! `PKG-9ED9285C` shape — which collides with ~69% probability once 100,000
//! IDs have been issued. Production systems should configure 64 bits:
//!
//! ```
//! use smart_package_tracker::{Checksum, IdGenerator};
//!
//! let generator = IdGenerator::builder()
//!     .entropy_bits(64)
//!     .checksum(Checksum::Iso7064Mod37_36)
//!     .build()?;
//! # Ok::<(), smart_package_tracker::Error>(())
//! ```
//!
//! See [`IdGenerator`] for the full collision table.
//!
//! # Feature flags
//!
//! | Feature | Default | Effect |
//! |---------|---------|--------|
//! | `std` | yes | File helpers and `std::error::Error`. Without it the crate is `no_std` + `alloc`. |
//! | `os-rng` | yes | Seed IDs from the OS CSPRNG. Turn off on targets `getrandom` does not support; `IdGenerator::generate_from_entropy` still works. |
//! | `code128` | yes | Code 128 encoding and decoding. |
//! | `qr` | yes | QR Code encoding. Implies `std`. |
//! | `png` | yes | PNG rendering. Implies `std`. |
//! | `svg` | yes | SVG rendering. No extra dependencies. |
//! | `serde` | no | `Serialize`/`Deserialize` for the public data types. |
//!
//! # Not yet implemented
//!
//! Image scanning, shipment events, and carrier integrations are deliberately
//! absent. The [`Symbology`](symbology::Symbology) and
//! [`Renderer`](render::Renderer) traits are the extension points for new
//! formats; carrier integrations belong in separate crates, so that network
//! I/O and vendor licence terms stay out of this dependency graph.
//!
//! QR Code is a registered trademark of Denso Wave Incorporated.

// The test harness needs `std`, so only apply `no_std` outside of it.
#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![forbid(unsafe_code)]
#![warn(
    missing_docs,
    missing_debug_implementations,
    rust_2018_idioms,
    unreachable_pub
)]

extern crate alloc;

pub mod error;
pub mod id;
pub mod render;
pub mod symbology;

mod barcode;

pub use barcode::Barcode;
pub use error::{Error, Result};
pub use id::{Checksum, IdGenerator, IdGeneratorBuilder, TrackingId};
pub use render::{hri_supports, Color, Length, QuietZone, RenderOptions, RenderOptionsBuilder};
pub use symbology::{Symbol, SymbologyKind};

#[cfg(feature = "code128")]
pub use symbology::Code128;
#[cfg(feature = "qr")]
pub use symbology::{Ecc, Qr, QrVersion};