1#[cfg(test)]
2mod tests {
3 use super::*;
4
5 #[test]
6 #[cfg(target_os = "linux")]
7 fn test_write_to_device_linux() {
8 let result = write_to_device("/dev/usb/lp0", "^FDhello world");
9 assert!(result.is_ok());
10 }
11
12 #[test]
13 #[cfg(target_os = "windows")]
14 fn test_write_to_device_windows() {
15 let result = write_to_device("ZDesigner ZD220-203dpi ZPL", "^FDhello world");
16 assert!(result.is_ok());
17 }
18}
19
20#[cfg(target_os = "linux")]
38pub fn write_to_device(printer: &str, payload: &str) -> Result<usize, std::io::Error> {
39 use std::fs::OpenOptions;
40 use std::io::Write;
41
42 let device_path = OpenOptions::new().write(true).open(printer);
43
44 match device_path {
45 Ok(mut device) => {
46 let bytes_written = device.write(payload.as_bytes())?;
47 Ok(bytes_written)
48 }
49 Err(e) => Err(std::io::Error::new(std::io::ErrorKind::Other, e)),
50 }
51}
52
53#[cfg(target_os = "windows")]
54pub fn write_to_device(printer: &str, payload: &str) -> Result<usize, std::io::Error> {
55 use std::ffi::CString;
56 use std::ptr;
57 use windows::Win32::Foundation::HANDLE;
58 use windows::Win32::Graphics::Printing::{
59 ClosePrinter, EndDocPrinter, EndPagePrinter, OpenPrinterA, StartDocPrinterA,
60 StartPagePrinter, WritePrinter, DOC_INFO_1A, PRINTER_ACCESS_USE, PRINTER_DEFAULTSA,
61 };
62
63 let printer_name = CString::new(printer).unwrap_or_default(); let mut printer_handle: HANDLE = HANDLE(std::ptr::null_mut());
65
66 unsafe {
68 let pd = PRINTER_DEFAULTSA {
69 pDatatype: windows::core::PSTR(ptr::null_mut()),
70 pDevMode: ptr::null_mut(),
71 DesiredAccess: PRINTER_ACCESS_USE,
72 };
73
74 if OpenPrinterA(
75 windows::core::PCSTR(printer_name.as_bytes().as_ptr()),
76 &mut printer_handle,
77 Some(&pd),
78 )
79 .is_ok()
80 {
81 let doc_info = DOC_INFO_1A {
82 pDocName: windows::core::PSTR("My Document\0".as_ptr() as *mut u8),
83 pOutputFile: windows::core::PSTR::null(),
84 pDatatype: windows::core::PSTR("RAW\0".as_ptr() as *mut u8),
85 };
86
87 let job = StartDocPrinterA(printer_handle, 1, &doc_info as *const _ as _);
89 if job == 0 {
90 return Err(std::io::Error::from(windows::core::Error::from_win32()));
91 }
92
93 if !StartPagePrinter(printer_handle).as_bool() {
95 return Err(std::io::Error::from(windows::core::Error::from_win32()));
96 }
97
98 let buffer = payload.as_bytes();
99
100 let mut bytes_written: u32 = 0;
101 if !WritePrinter(
102 printer_handle,
103 buffer.as_ptr() as _,
104 buffer.len() as u32,
105 &mut bytes_written,
106 )
107 .as_bool()
108 {
109 return Err(std::io::Error::from(windows::core::Error::from_win32()));
110 }
111
112 let _ = EndPagePrinter(printer_handle);
114 let _ = EndDocPrinter(printer_handle);
115 let _ = ClosePrinter(printer_handle);
116 return Ok(bytes_written as usize);
117 } else {
118 return Err(std::io::Error::from(windows::core::Error::from_win32()));
119 }
120 }
121}