1use std::{collections::HashMap, sync::LazyLock};
2
3use enumflags2::{BitFlags, bitflags};
4
5static USB_TO_DEVICE: LazyLock<HashMap<(u16, u16), PrinterType>> = LazyLock::new(|| {
6 let mut map = HashMap::new();
7
8 for (printer, info) in PrinterType::iter_info() {
9 map.insert((info.vendor_id, info.product_id), *printer);
10 }
11
12 map
13});
14
15static INFO: LazyLock<HashMap<PrinterType, PrinterInfo>> = LazyLock::new(|| {
16 let mut map = HashMap::new();
17
18 for printer in PrinterType::iter() {
19 map.insert(printer, printer.info());
20 }
21
22 map
23});
24
25#[bitflags]
26#[repr(u8)]
27#[derive(Debug, Clone, Copy, PartialEq)]
28#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
29pub enum PrinterFlags {
30 UnsupportedRaster = (1 << 0),
31 RasterPackBits = (1 << 1),
32 PLite = (1 << 2),
33 P700Init = (1 << 3),
34 UseInfoCmd = (1 << 4),
35 HasPrecut = (1 << 5),
36 D460BTMagic = (1 << 6),
37}
38
39#[derive(Debug, Clone)]
40#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
41pub struct PrinterInfo {
42 pub vendor_id: u16,
43 pub product_id: u16,
44 pub max_px: u32,
45 pub dpi: u32,
46 pub flags: BitFlags<PrinterFlags>,
47}
48
49#[allow(non_camel_case_types)]
50#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::EnumIter)]
51#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
52pub enum PrinterType {
53 PT_9200DX,
54 PT_2300,
55 PT_2420PC,
56 PT_2450PC,
57 PT_1950,
58 PT_2700,
59 PT_1230PC,
61 PT_2430PC,
62 PT_1230PC_PLite,
63 PT_2430PC_PLite,
64 PT_2730,
66 PT_H500,
68 PT_E500,
70 PT_P700,
71 PT_P750W,
72 PT_P700_PLite,
73 PT_P750W_PLite,
74 PT_D410,
75 PT_D450,
77 PT_D460BT,
78 PT_D600,
80 PT_D610BT,
81 PT_P710BT,
82 PT_E310BT,
87}
88
89impl PrinterType {
90 pub fn from_usb(vendor: u16, product: u16) -> Option<Self> {
91 USB_TO_DEVICE.get(&(vendor, product)).cloned()
92 }
93
94 pub fn iter() -> impl Iterator<Item = Self> {
95 <Self as strum::IntoEnumIterator>::iter()
96 }
97
98 pub fn iter_info() -> impl Iterator<Item = (&'static Self, &'static PrinterInfo)> {
99 INFO.iter()
100 }
101
102 pub fn info(&self) -> PrinterInfo {
103 match self {
104 PrinterType::PT_9200DX => PrinterInfo {
105 vendor_id: 0x04f9,
106 product_id: 0x2001,
107 max_px: 384,
108 dpi: 360,
109 flags: PrinterFlags::RasterPackBits | PrinterFlags::HasPrecut,
110 },
111 PrinterType::PT_2300 => PrinterInfo {
112 vendor_id: 0x04f9,
113 product_id: 0x2004,
114 max_px: 112,
115 dpi: 180,
116 flags: PrinterFlags::RasterPackBits | PrinterFlags::HasPrecut,
117 },
118 PrinterType::PT_2420PC => PrinterInfo {
119 vendor_id: 0x04f9,
120 product_id: 0x2007,
121 max_px: 128,
122 dpi: 180,
123 flags: PrinterFlags::RasterPackBits.into(),
124 },
125 PrinterType::PT_2450PC => PrinterInfo {
126 vendor_id: 0x04f9,
127 product_id: 0x2011,
128 max_px: 128,
129 dpi: 180,
130 flags: PrinterFlags::RasterPackBits.into(),
131 },
132 PrinterType::PT_1950 => PrinterInfo {
133 vendor_id: 0x04f9,
134 product_id: 0x2019,
135 max_px: 112,
136 dpi: 180,
137 flags: PrinterFlags::RasterPackBits.into(),
138 },
139 PrinterType::PT_2700 => PrinterInfo {
140 vendor_id: 0x04f9,
141 product_id: 0x201f,
142 max_px: 128,
143 dpi: 180,
144 flags: PrinterFlags::HasPrecut.into(),
145 },
146 PrinterType::PT_1230PC => PrinterInfo {
147 vendor_id: 0x04f9,
148 product_id: 0x202c,
149 max_px: 128,
150 dpi: 180,
151 flags: BitFlags::empty(),
152 },
153 PrinterType::PT_2430PC => PrinterInfo {
154 vendor_id: 0x04f9,
155 product_id: 0x202d,
156 max_px: 128,
157 dpi: 180,
158 flags: BitFlags::empty(),
159 },
160 PrinterType::PT_1230PC_PLite => PrinterInfo {
161 vendor_id: 0x04f9,
162 product_id: 0x2030,
163 max_px: 128,
164 dpi: 180,
165 flags: PrinterFlags::PLite.into(),
166 },
167 PrinterType::PT_2430PC_PLite => PrinterInfo {
168 vendor_id: 0x04f9,
169 product_id: 0x2031,
170 max_px: 128,
171 dpi: 180,
172 flags: PrinterFlags::PLite.into(),
173 },
174 PrinterType::PT_2730 => PrinterInfo {
175 vendor_id: 0x04f9,
176 product_id: 0x2041,
177 max_px: 128,
178 dpi: 180,
179 flags: BitFlags::empty(),
180 },
181 PrinterType::PT_H500 => PrinterInfo {
182 vendor_id: 0x04f9,
183 product_id: 0x205e,
184 max_px: 128,
185 dpi: 180,
186 flags: PrinterFlags::RasterPackBits.into(),
187 },
188 PrinterType::PT_E500 => PrinterInfo {
189 vendor_id: 0x04f9,
190 product_id: 0x205f,
191 max_px: 128,
192 dpi: 180,
193 flags: PrinterFlags::RasterPackBits.into(),
194 },
195 PrinterType::PT_P700 => PrinterInfo {
196 vendor_id: 0x04f9,
197 product_id: 0x2061,
198 max_px: 128,
199 dpi: 180,
200 flags: PrinterFlags::RasterPackBits | PrinterFlags::P700Init | PrinterFlags::HasPrecut,
201 },
202 PrinterType::PT_P750W => PrinterInfo {
203 vendor_id: 0x04f9,
204 product_id: 0x2062,
205 max_px: 128,
206 dpi: 180,
207 flags: PrinterFlags::RasterPackBits | PrinterFlags::P700Init,
208 },
209 PrinterType::PT_P700_PLite => PrinterInfo {
210 vendor_id: 0x04f9,
211 product_id: 0x2064,
212 max_px: 128,
213 dpi: 180,
214 flags: PrinterFlags::PLite.into(),
215 },
216 PrinterType::PT_P750W_PLite => PrinterInfo {
217 vendor_id: 0x04f9,
218 product_id: 0x2065,
219 max_px: 128,
220 dpi: 180,
221 flags: PrinterFlags::PLite.into(),
222 },
223 PrinterType::PT_D410 => PrinterInfo {
224 vendor_id: 0x04f9,
225 product_id: 0x20df,
226 max_px: 128,
227 dpi: 180,
228 flags: PrinterFlags::UseInfoCmd | PrinterFlags::HasPrecut | PrinterFlags::D460BTMagic,
229 },
230 PrinterType::PT_D450 => PrinterInfo {
231 vendor_id: 0x04f9,
232 product_id: 0x2073,
233 max_px: 128,
234 dpi: 180,
235 flags: PrinterFlags::UseInfoCmd.into(),
236 },
237 PrinterType::PT_D460BT => PrinterInfo {
238 vendor_id: 0x04f9,
239 product_id: 0x20e0,
240 max_px: 128,
241 dpi: 180,
242 flags: PrinterFlags::P700Init
243 | PrinterFlags::UseInfoCmd
244 | PrinterFlags::HasPrecut
245 | PrinterFlags::D460BTMagic,
246 },
247 PrinterType::PT_D600 => PrinterInfo {
248 vendor_id: 0x04f9,
249 product_id: 0x2074,
250 max_px: 128,
251 dpi: 180,
252 flags: PrinterFlags::RasterPackBits.into(),
253 },
254 PrinterType::PT_D610BT => PrinterInfo {
255 vendor_id: 0x04f9,
256 product_id: 0x20e1,
257 max_px: 128,
258 dpi: 180,
259 flags: PrinterFlags::P700Init
260 | PrinterFlags::UseInfoCmd
261 | PrinterFlags::HasPrecut
262 | PrinterFlags::D460BTMagic,
263 },
264 PrinterType::PT_P710BT => PrinterInfo {
265 vendor_id: 0x04f9,
266 product_id: 0x20af,
267 max_px: 128,
268 dpi: 180,
269 flags: PrinterFlags::RasterPackBits | PrinterFlags::HasPrecut,
270 },
271 PrinterType::PT_E310BT => PrinterInfo {
272 vendor_id: 0x04f9,
273 product_id: 0x2201,
274 max_px: 128,
275 dpi: 180,
276 flags: PrinterFlags::P700Init | PrinterFlags::UseInfoCmd | PrinterFlags::D460BTMagic,
277 },
278 }
279 }
280}