pub struct PrinterMonitor { /* private fields */ }Expand description
Printer monitoring and querying functionality
PrinterMonitor is cheaply cloneable (uses Arc internally) and can be
shared across tasks without creating multiple backend connections.
Implementations§
Source§impl PrinterMonitor
impl PrinterMonitor
Sourcepub async fn new() -> Result<Self>
pub async fn new() -> Result<Self>
Creates a new PrinterMonitor instance with the appropriate platform backend.
This function automatically selects and initializes the correct backend for the current platform (WMI for Windows, CUPS for Linux).
§Returns
Result<Self>- A new PrinterMonitor instance or an error if initialization fails
§Errors
PrinterError::PlatformNotSupported- If the current platform is not supportedPrinterError::WmiError- If WMI initialization fails on WindowsPrinterError::CupsError- If CUPS initialization fails on Linux
§Example
use printer_event_handler::PrinterMonitor;
#[tokio::main]
async fn main() {
let monitor = PrinterMonitor::new().await.unwrap();
}Sourcepub async fn list_printers(&self) -> Result<Vec<Printer>>
pub async fn list_printers(&self) -> Result<Vec<Printer>>
Retrieves a list of all printers available on the system.
This method queries the platform-specific printer service to get information about all installed and available printers.
§Returns
Result<Vec<Printer>>- A vector of all printers found on the system
§Errors
PrinterError::WmiError- If the WMI query fails on WindowsPrinterError::CupsError- If the CUPS query fails on LinuxPrinterError::IoError- If there are system I/O issues
§Example
use printer_event_handler::PrinterMonitor;
#[tokio::main]
async fn main() {
let monitor = PrinterMonitor::new().await.unwrap();
let printers = monitor.list_printers().await.unwrap();
for printer in printers {
println!("{}: {}", printer.name(), printer.status_description());
}
}Sourcepub async fn find_printer(&self, name: &str) -> Result<Option<Printer>>
pub async fn find_printer(&self, name: &str) -> Result<Option<Printer>>
Searches for a specific printer by name using case-insensitive matching.
This method searches through all available printers to find one with a name that matches the provided string (case-insensitive).
§Arguments
name- The name of the printer to search for
§Returns
Result<Option<Printer>>- The found printer or None if not found
§Errors
PrinterError::WmiError- If the WMI query fails on WindowsPrinterError::CupsError- If the CUPS query fails on LinuxPrinterError::IoError- If there are system I/O issues
§Example
use printer_event_handler::PrinterMonitor;
#[tokio::main]
async fn main() {
let monitor = PrinterMonitor::new().await.unwrap();
if let Some(printer) = monitor.find_printer("HP LaserJet").await.unwrap() {
println!("Found printer: {}", printer.name());
}
}Sourcepub async fn monitor_printer<F>(
&self,
printer_name: &str,
interval_ms: u64,
cancel_token: Option<CancellationToken>,
callback: F,
) -> Result<()>
pub async fn monitor_printer<F>( &self, printer_name: &str, interval_ms: u64, cancel_token: Option<CancellationToken>, callback: F, ) -> Result<()>
Continuously monitors a specific printer for status changes.
This function runs indefinitely, polling the specified printer every interval_ms
milliseconds and calling the provided callback function whenever the printer’s status changes.
The callback receives both the current printer state and the previous state (if any).
§Arguments
printer_name- The name of the printer to monitorinterval_ms- Polling interval in millisecondscallback- Function called when printer status changes, receives (current, previous)
§Returns
Result<()>- Never returns Ok normally (runs indefinitely), only Err on failure
§Errors
PrinterError::PrinterNotFound- If the specified printer is not found initiallyPrinterError::WmiError- If WMI queries fail on WindowsPrinterError::CupsError- If CUPS queries fail on LinuxPrinterError::IoError- If there are system I/O issues
§Behavior
- If the printer disappears during monitoring, the callback is called with a synthetic “unknown” status to indicate the printer is no longer available
- The first check always triggers the callback to provide the initial status
- Subsequent calls only trigger the callback if the status actually changes
§Example
use printer_event_handler::PrinterMonitor;
use tokio_util::sync::CancellationToken;
#[tokio::main]
async fn main() {
let monitor = PrinterMonitor::new().await.unwrap();
let cancel_token = CancellationToken::new();
monitor.monitor_printer("HP LaserJet", 30000, Some(cancel_token.clone()), |current, previous| {
if let Some(prev) = previous {
if prev != current {
println!("Status changed: {} -> {}",
prev.status_description(),
current.status_description());
}
} else {
println!("Initial status: {}", current.status_description());
}
}).await.unwrap();
}Sourcepub async fn printer_summary(&self) -> Result<HashMap<String, PrinterSummary>>
pub async fn printer_summary(&self) -> Result<HashMap<String, PrinterSummary>>
Retrieves a comprehensive summary of all printers and their current states.
This method provides a convenient way to get an overview of all printers in a structured format, useful for status dashboards or reports.
§Returns
Result<HashMap<String, PrinterSummary>>- Map of printer names to their summaries
§Errors
PrinterError::WmiError- If the WMI query fails on WindowsPrinterError::CupsError- If the CUPS query fails on LinuxPrinterError::IoError- If there are system I/O issues
§Example
use printer_event_handler::PrinterMonitor;
#[tokio::main]
async fn main() {
let monitor = PrinterMonitor::new().await.unwrap();
let summary = monitor.printer_summary().await.unwrap();
for (name, info) in summary {
println!("{}: {} ({})", name, info.status,
if info.has_error { "ERROR" } else { "OK" });
}
}Sourcepub async fn monitor_printer_changes<F>(
&self,
printer_name: &str,
interval_ms: u64,
cancel_token: Option<CancellationToken>,
callback: F,
) -> Result<()>
pub async fn monitor_printer_changes<F>( &self, printer_name: &str, interval_ms: u64, cancel_token: Option<CancellationToken>, callback: F, ) -> Result<()>
Monitors a printer with detailed property change detection.
This enhanced monitoring method provides detailed information about exactly which properties changed between checks, enabling fine-grained monitoring and alerting.
§Arguments
printer_name- The name of the printer to monitorinterval_ms- Polling interval in millisecondscancel_token- Optional cancellation token for graceful shutdowncallback- Function called when properties change, receives PrinterChanges
§Returns
Result<()>- Returns Ok when cancelled, or Err on failure
§Behavior
- The callback is NOT called on the initial state capture
- Only actual property changes trigger the callback
- Changes are always non-empty when the callback is invoked
- The initial state is captured silently for comparison with future states
- Monitoring stops gracefully when the cancellation token is cancelled
§Example
use printer_event_handler::PrinterMonitor;
use tokio_util::sync::CancellationToken;
#[tokio::main]
async fn main() {
let monitor = PrinterMonitor::new().await.unwrap();
let cancel_token = CancellationToken::new();
// Clone the token for the monitoring task
let token_clone = cancel_token.clone();
let handle = tokio::spawn(async move {
monitor.monitor_printer_changes("HP LaserJet", 30000, Some(token_clone), |changes| {
println!("Detected {} changes:", changes.change_count());
for change in &changes.changes {
println!(" - {}", change.description());
}
}).await
});
// Later: cancel monitoring
cancel_token.cancel();
handle.await.unwrap().unwrap();
}Sourcepub async fn monitor_property<F>(
&self,
printer_name: &str,
property: MonitorableProperty,
interval_ms: u64,
cancel_token: Option<CancellationToken>,
callback: F,
) -> Result<()>
pub async fn monitor_property<F>( &self, printer_name: &str, property: MonitorableProperty, interval_ms: u64, cancel_token: Option<CancellationToken>, callback: F, ) -> Result<()>
Monitors a specific property of a printer for changes.
This method allows monitoring just a single property, useful for alerting on specific conditions like offline status or error state changes.
§Arguments
printer_name- The name of the printer to monitorproperty- The specific property to watch using MonitorableProperty enuminterval_ms- Polling interval in millisecondscancel_token- Optional cancellation token for graceful shutdowncallback- Function called when the property changes
§Example
use printer_event_handler::{PrinterMonitor, MonitorableProperty};
use tokio_util::sync::CancellationToken;
#[tokio::main]
async fn main() {
let monitor = PrinterMonitor::new().await.unwrap();
let cancel_token = CancellationToken::new();
monitor.monitor_property(
"HP LaserJet",
MonitorableProperty::IsOffline,
60000,
Some(cancel_token.clone()),
|change| {
println!("Offline status changed: {}", change.description());
}
).await.unwrap();
}Sourcepub async fn monitor_multiple_printers<F>(
&self,
printer_names: Vec<String>,
interval_ms: u64,
cancel_token: Option<CancellationToken>,
callback: F,
) -> Result<()>
pub async fn monitor_multiple_printers<F>( &self, printer_names: Vec<String>, interval_ms: u64, cancel_token: Option<CancellationToken>, callback: F, ) -> Result<()>
Monitors multiple printers concurrently and reports changes for any of them.
This method allows monitoring several printers simultaneously, with a single callback that receives changes from any of the monitored printers.
§Arguments
printer_names- List of printer names to monitorinterval_ms- Polling interval in millisecondscancel_token- Optional cancellation token for graceful shutdowncallback- Function called when any printer changes (NOT called on initial state)
§Returns
Result<()>- Returns Ok when cancelled or all tasks complete, or Err on failure
§Behavior
- The callback is NOT called on the initial state capture for each printer
- Only actual property changes trigger the callback
- Each printer is monitored in a separate task for true concurrent monitoring
- Callbacks are called outside of internal locks to prevent contention with slow callbacks
- The monitor is cloned (cheaply via Arc) for each task, sharing the same backend connection
- Monitoring stops gracefully when the cancellation token is cancelled
§Example
use printer_event_handler::PrinterMonitor;
use tokio_util::sync::CancellationToken;
#[tokio::main]
async fn main() {
let monitor = PrinterMonitor::new().await.unwrap();
let printers = vec!["HP LaserJet".to_string(), "Canon Printer".to_string()];
let cancel_token = CancellationToken::new();
let token_clone = cancel_token.clone();
let handle = tokio::spawn(async move {
monitor.monitor_multiple_printers(printers, 30000, Some(token_clone), |changes| {
println!("Printer '{}' changed: {}", changes.printer_name, changes.summary());
}).await
});
// Later: cancel monitoring
cancel_token.cancel();
handle.await.unwrap().unwrap();
}Trait Implementations§
Source§impl Clone for PrinterMonitor
impl Clone for PrinterMonitor
Source§fn clone(&self) -> PrinterMonitor
fn clone(&self) -> PrinterMonitor
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more