commit 0fce887161566ce9c8243d5a407958931917a59d from: Benjamins Stürz date: Fri Feb 07 23:19:34 2025 UTC add Printer::list() commit - 67440028473df7a5c413d092925a60f26f9c8a11 commit + 0fce887161566ce9c8243d5a407958931917a59d blob - 730cfc6ef5534dad927f734b1577536d353e57f3 blob + 3906686cb169083da6d06e2a4a99d1d662d924ab --- ppa6/src/lib.rs +++ ppa6/src/lib.rs @@ -1,7 +1,7 @@ // Very helpful doc for USB: https://www.beyondlogic.org/usbnutshell/usb1.shtml use std::{iter::repeat_n, time::Duration}; -use rusb::{Context, DeviceHandle, Direction, TransferType, UsbContext}; +use rusb::{Context, Direction, TransferType, UsbContext}; use thiserror::Error; pub use crate::doc::{Document, DocumentError}; @@ -25,22 +25,25 @@ pub enum Error { NoPrinter, } +pub type Device = rusb::Device; +pub type DeviceHandle = rusb::DeviceHandle; pub type Result = core::result::Result; mod doc; pub struct Printer { - handle: DeviceHandle, + handle: DeviceHandle, epin: u8, epout: u8, } impl Printer { - pub fn find(ctx: &Context) -> Result { - let dev = ctx + /// List all available printers. + pub fn list(ctx: &Context) -> Result> { + let devs = ctx .devices()? .iter() - .find(|dev| { + .filter(|dev| { let Ok(desc) = dev.device_descriptor() else { log::warn!("cannot get device descriptor for Bus {dev:?}"); return false @@ -48,11 +51,19 @@ impl Printer { desc.vendor_id() == VENDOR_ID && desc.product_id() == PRODUCT_ID }) - .ok_or(Error::NoPrinter)?; - - Self::open(dev.open()?) + .collect(); + Ok(devs) } - pub fn open(handle: DeviceHandle) -> Result { + + /// Find the first printer and open it. + pub fn find(ctx: &Context) -> Result { + match Self::list(ctx)?.first() { + Some(dev) => Self::open(dev.open()?), + None => Err(Error::NoPrinter), + } + } + /// Open a specific printer. + pub fn open(handle: DeviceHandle) -> Result { let dev = handle.device(); // automatically steal the USB device from the kernel @@ -179,7 +190,7 @@ impl Printer { }) } - pub fn handle(&mut self) -> &DeviceHandle { + pub fn handle(&mut self) -> &DeviceHandle { &mut self.handle } pub fn endpoint_in(&self) -> u8 {