zpl_forge/lib.rs
1//! # ZPL-Forge
2//!
3//! `zpl-forge` is a high-performance engine for parsing, processing, and rendering Zebra Programming Language (ZPL) labels.
4//! It transforms raw ZPL strings into an optimized Intermediate Representation (IR), which can then be exported to various
5//! formats like PNG images or PDF documents.
6//!
7//! ## Core Features
8//! - **Robust Parsing**: Uses `nom` for fast and safe ZPL command parsing.
9//! - **State Machine**: Maintains label state (fonts, positions, barcodes) across commands.
10//! - **Multiple Backends**: Native support for PNG (via `imageproc`) and PDF (via `lopdf`).
11//! - **Extensible**: Includes custom commands for color support and Base64 image loading.
12//! - **Security**: Built-in OOM protection and safe arithmetic for coordinate calculations.
13//!
14//! ## Quick Start
15//!
16//! Rendering a simple label to a PNG image:
17//!
18//! ```rust
19//! use zpl_forge::{ZplEngine, Unit, Resolution};
20//! use zpl_forge::forge::png::PngBackend;
21//! use std::collections::HashMap;
22//!
23//! # fn main() -> zpl_forge::ZplResult<()> {
24//! let zpl_input = "^XA^FO50,50^A0N,50,50^FDZPL Forge^FS^XZ";
25//!
26//! // Create the engine by parsing ZPL data
27//! let engine = ZplEngine::new(
28//! zpl_input,
29//! Unit::Inches(4.0),
30//! Unit::Inches(2.0),
31//! Resolution::Dpi203
32//! )?;
33//!
34//! // Render using the PNG backend
35//! let backend = PngBackend::new();
36//! let png_bytes = engine.render(backend, &HashMap::new())?;
37//!
38//! // png_bytes now contains the raw PNG data
39//! # Ok(())
40//! # }
41//! ```
42//!
43//! ## Security and Limits
44//!
45//! To ensure stability and prevent Denial of Service (DoS) attacks via malformed input, `zpl-forge` implements the following restrictions:
46//! - **Canvas Size**: Rendering is limited to a maximum of **8192 x 8192 pixels**.
47//! - **Image Data**: Decoded bitmap data (`^GF`) cannot exceed **10 MB** per command.
48//! - **Safe Calculations**: Saturating arithmetic is used for all coordinate and dimension calculations to prevent integer overflows.
49//! - **Unit Normalization**: Input values for physical dimensions are validated to prevent negative sizes.
50
51#![forbid(unsafe_code)]
52
53mod ast;
54mod engine;
55pub mod error;
56pub mod forge;
57pub mod tools;
58
59pub use engine::*;
60pub use error::{ZplError, ZplResult};
61
62#[cfg(feature = "tracing")]
63pub(crate) const TARGET: &str = "zpl-forge";
64
65/// Renders a ZPL string directly to native vector PDF bytes using default label dimensions (4x6 inches at 203 DPI).
66///
67/// # Arguments
68/// * `zpl` - The raw ZPL string to render.
69///
70/// # Returns
71/// A `ZplResult<Vec<u8>>` containing the raw PDF document bytes.
72///
73/// # Errors
74/// Returns [`ZplError::ParseError`] if the ZPL string contains malformed syntax, or [`ZplError::EmptyInput`] if input is empty.
75#[cfg(feature = "pdf")]
76pub fn render_pdf(zpl: &str) -> ZplResult<Vec<u8>> {
77 let engine = ZplEngine::new(
78 zpl,
79 Unit::Inches(4.0),
80 Unit::Inches(6.0),
81 Resolution::Dpi203,
82 )?;
83 engine.to_pdf()
84}
85
86/// Renders a ZPL string directly to PNG image bytes using default label dimensions (4x6 inches at 203 DPI).
87///
88/// # Arguments
89/// * `zpl` - The raw ZPL string to render.
90///
91/// # Returns
92/// A `ZplResult<Vec<u8>>` containing the raw PNG image bytes.
93///
94/// # Errors
95/// Returns [`ZplError::ParseError`] if the ZPL string contains malformed syntax, or [`ZplError::EmptyInput`] if input is empty.
96#[cfg(feature = "png")]
97pub fn render_png(zpl: &str) -> ZplResult<Vec<u8>> {
98 let engine = ZplEngine::new(
99 zpl,
100 Unit::Inches(4.0),
101 Unit::Inches(6.0),
102 Resolution::Dpi203,
103 )?;
104 engine.to_png()
105}