1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
//! Rust driver for Brother QL series label printers
//!
//! Convert images to Brother QL Raster Command binary data and print labels via USB or kernel drivers.
//!
//! # Features
//!
//! - **Print directly** via USB ([`UsbConnection`](connection::UsbConnection)) or Linux kernel driver ([`KernelConnection`](connection::KernelConnection))
//! - **Compile to file** for network printing or debugging
//! - **Multiple label types** - Continuous rolls and die-cut labels in various sizes
//! - **Two-color printing** - Black/red support on compatible printers
//! - **Full status monitoring** - Check errors, media type, and printer state
//!
//! # Supported Printers
//!
//! Brother QL series: **5xx** (QL-560, QL-570, QL-580N), **6xx** (QL-600, QL-650TD),
//! **7xx** (QL-700, QL-710W, QL-720NW), **8xx** (QL-800, QL-810W, QL-820NWB)
//!
//! See [`printer`] module for complete list and testing status.
//!
//! # Feature Flags
//!
//! - **`usb`** (optional) - Enables USB printing via the `rusb` crate. Provides [`UsbConnection`](connection::UsbConnection)
//! and [`UsbConnectionInfo`](connection::UsbConnectionInfo).
//! - **`serde`** (optional) - Enables serialization support for [`Media`] and [`CutBehavior`](printjob::CutBehavior).
//!
//! The crate has **no default features**. Basic print job compilation and [`KernelConnection`](connection::KernelConnection)
//! work without any features enabled.
//!
//! # Quick Start
//!
//! ## USB Printing (requires `usb` feature)
//!
//! ```no_run
//! use brother_ql::{
//! connection::{PrinterConnection, UsbConnection, UsbConnectionInfo},
//! media::Media,
//! printer::PrinterModel,
//! printjob::PrintJobBuilder,
//! };
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // Connect to a specific printer model
//! let info = UsbConnectionInfo::from_model(PrinterModel::QL820NWB);
//! let mut connection = UsbConnection::open(info)?;
//!
//! // Create and print a label
//! let img = image::open("label.png")?;
//! let job = PrintJobBuilder::new(Media::C62)
//! .add_label(img)
//! .build()?;
//! connection.print(job)?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Kernel Driver Printing (Linux, no features required)
//!
//! ```no_run
//! use brother_ql::{
//! connection::{KernelConnection, PrinterConnection},
//! media::Media,
//! printjob::PrintJobBuilder,
//! };
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let mut connection = KernelConnection::open("/dev/usb/lp0")?;
//! let img = image::open("label.png")?;
//! let job = PrintJobBuilder::new(Media::C62)
//! .add_label(img)
//! .build()?;
//! connection.print(job)?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Compile to File (no features required)
//!
//! ```no_run
//! use brother_ql::{media::Media, printjob::PrintJobBuilder};
//! use std::{fs::File, io::Write};
//!
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let img = image::open("label.png")?;
//! let job = PrintJobBuilder::new(Media::C62)
//! .add_label(img)
//! .build()?;
//!
//! // Compile to binary data
//! let data = job.compile();
//!
//! // Save to file (can be sent via network: `nc printer-ip 9100 < output.bin`)
//! File::create("output.bin")?.write_all(&data)?;
//! # Ok(())
//! # }
//! ```
//!
//! # Choosing Media
//!
//! Media types determine label dimensions and behavior:
//!
//! - **Continuous rolls** (`C` prefix like `C62`) - Cut to any length
//! - **Die-cut labels** (`D` prefix like `D17x54`) - Pre-cut, fixed dimensions
//! - **Two-color** (`R` suffix like `C62R`) - Black/red printing support
//!
//! All media types require **720 pixels wide** images at 300 DPI. Height varies by media type.
//! See [`media`] module for complete details.
//!
//! # Print Job Configuration
//!
//! Use [`PrintJobBuilder`](printjob::PrintJobBuilder) for advanced customization:
//!
//! ```no_run
//! # use brother_ql::{media::Media, printjob::{PrintJobBuilder, CutBehavior}};
//! # use std::num::NonZeroU8;
//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
//! # let img1 = image::open("label1.png")?;
//! # let img2 = image::open("label2.png")?;
//! let job = PrintJobBuilder::new(Media::C62)
//! .add_label(img1) // Add first image
//! .add_label(img2) // Add second image
//! .copies(NonZeroU8::new(5).unwrap()) // Print 5 copies of each
//! .high_dpi(false) // 300 DPI (default)
//! .quality_priority(true) // Quality over speed (default)
//! .cut_behavior(CutBehavior::CutEvery(NonZeroU8::new(2).unwrap())) // Cut every 2 labels
//! .build()?;
//! # Ok(())
//! # }
//! ```
//!
//! See [`PrintJob`] and [`PrintJobBuilder`](printjob::PrintJobBuilder) for defaults and all options.
//!
//! # Status Monitoring
//!
//! Check printer status, errors, and media information:
//!
//! ```no_run
//! # use brother_ql::connection::{PrinterConnection, UsbConnection, UsbConnectionInfo};
//! # use brother_ql::printer::PrinterModel;
//! # fn example() -> Result<(), Box<dyn std::error::Error>> {
//! # let info = UsbConnectionInfo::from_model(PrinterModel::QL820NWB);
//! # let mut connection = UsbConnection::open(info)?;
//! let status = connection.get_status()?;
//!
//! println!("Model: {:?}", status.model);
//! println!("Media: {}mm wide", status.media_width);
//!
//! if status.has_errors() {
//! eprintln!("Errors: {:?}", status.errors);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! See [`status`] module for complete status information.
//!
//! # References
//!
//! - [Official Raster Command Reference](https://download.brother.com/welcome/docp100278/cv_ql800_eng_raster_101.pdf)
//! - Images are processed using the [`image`] crate
//!
//! [`Media`]: media::Media
//! [`PrintJob`]: printjob::PrintJob