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", Some("Test Document"));
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", Some("Test Document"));
16 assert!(result.is_ok());
17 }
18}
19
20#[cfg(target_os = "linux")]
38pub fn write_to_device(printer: &str, payload: &str, _document_name: Option<&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, document_name: Option<&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_name = document_name.unwrap_or("Print Job");
82 let doc_name_cstring = CString::new(doc_name).unwrap_or_default();
83
84 let doc_info = DOC_INFO_1A {
85 pDocName: windows::core::PSTR(doc_name_cstring.as_ptr() as *mut u8),
86 pOutputFile: windows::core::PSTR::null(),
87 pDatatype: windows::core::PSTR("RAW\0".as_ptr() as *mut u8),
88 };
89
90 let job = StartDocPrinterA(printer_handle, 1, &doc_info as *const _ as _);
92 if job == 0 {
93 return Err(std::io::Error::from(windows::core::Error::from_win32()));
94 }
95
96 if !StartPagePrinter(printer_handle).as_bool() {
98 return Err(std::io::Error::from(windows::core::Error::from_win32()));
99 }
100
101 let buffer = payload.as_bytes();
102
103 let mut bytes_written: u32 = 0;
104 if !WritePrinter(
105 printer_handle,
106 buffer.as_ptr() as _,
107 buffer.len() as u32,
108 &mut bytes_written,
109 )
110 .as_bool()
111 {
112 return Err(std::io::Error::from(windows::core::Error::from_win32()));
113 }
114
115 let _ = EndPagePrinter(printer_handle);
117 let _ = EndDocPrinter(printer_handle);
118 let _ = ClosePrinter(printer_handle);
119 return Ok(bytes_written as usize);
120 } else {
121 return Err(std::io::Error::from(windows::core::Error::from_win32()));
122 }
123 }
124}