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 fn monitor(&self, printer_name: impl Into<String>) -> MonitorBuilder<'_>
pub fn monitor(&self, printer_name: impl Into<String>) -> MonitorBuilder<'_>
Starts a fluent monitoring run via MonitorBuilder.
Replaces the positional-parameter monitor_printer* methods for new
code. The old methods remain available (the builder delegates to them
internally) but the builder form is the recommended entry point.
Source§impl PrinterMonitor
impl PrinterMonitor
Sourcepub async fn list_printers_cancellable(
&self,
cancel_token: Option<CancellationToken>,
) -> Result<Vec<Printer>>
pub async fn list_printers_cancellable( &self, cancel_token: Option<CancellationToken>, ) -> Result<Vec<Printer>>
Retrieves a list of all printers available on the system, with an
optional CancellationToken to abort the in-flight backend query.
When cancel_token is provided, the backend query is raced against
token.cancelled() and the call returns [PrinterError::Cancelled]
as soon as the token fires. Passing None waits for the query to
complete normally.
Note that the backend query (a WMI call on Windows, an lpstat exec
or libcups call on Linux) is not itself abortable - cancellation
surfaces as soon as the current poll completes, not mid-flight.
§Example
use printer_event_handler::PrinterMonitor;
let monitor = PrinterMonitor::new().await.unwrap();
let printers = monitor.list_printers_cancellable(None).await.unwrap();
for printer in printers {
println!("{}: {}", printer.name(), printer.status_description());
}Sourcepub async fn find_printer_cancellable(
&self,
name: &str,
cancel_token: Option<CancellationToken>,
) -> Result<Option<Printer>>
pub async fn find_printer_cancellable( &self, name: &str, cancel_token: Option<CancellationToken>, ) -> Result<Option<Printer>>
Searches for a specific printer by name (case-insensitive), with an
optional CancellationToken.
See Self::list_printers_cancellable for the cancellation
semantics (token races against the in-flight backend query and yields
[PrinterError::Cancelled]).
§Example
use printer_event_handler::PrinterMonitor;
let monitor = PrinterMonitor::new().await.unwrap();
if let Some(p) = monitor.find_printer_cancellable("HP LaserJet", None).await.unwrap() {
println!("Found printer: {}", p.name());
}Sourcepub async fn list_jobs(
&self,
printer_name: Option<&str>,
cancel_token: Option<CancellationToken>,
) -> Result<Vec<Job>>
pub async fn list_jobs( &self, printer_name: Option<&str>, cancel_token: Option<CancellationToken>, ) -> Result<Vec<Job>>
Lists print jobs across all printers (printer_name = None) or for a
single printer (Some(name)).
Backends that cannot enumerate jobs return Ok(vec![]) - this is the
case for the Linux/CUPS backend in 1.5.0; first-class CUPS support is
queued for a later release. The Windows backend pulls from WMI’s
Win32_PrintJob.
The optional CancellationToken is raced against the backend query;
when fired the call returns crate::PrinterError::Cancelled.
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
Offlinesnapshot 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 printer_summary_iter(
&self,
) -> Result<impl Iterator<Item = (String, PrinterSummary)>>
pub async fn printer_summary_iter( &self, ) -> Result<impl Iterator<Item = (String, PrinterSummary)>>
Iterator counterpart to Self::printer_summary.
Returns the same (name, summary) pairs without allocating a
HashMap. Prefer this when you just need to iterate once - for
example to log every printer or feed a UI list - and don’t need
key-based lookup.
Order matches the underlying backend’s enumeration order (insertion
order via the source Vec<Printer>), not the unspecified order a
HashMap iterator would yield.
§Errors
Same errors as Self::printer_summary.
§Example
use printer_event_handler::PrinterMonitor;
#[tokio::main]
async fn main() {
let monitor = PrinterMonitor::new().await.unwrap();
for (name, info) in monitor.printer_summary_iter().await.unwrap() {
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
- Disappearance fires a synthetic
IsOffline: false -> truechange - Reappearance fires a change set comparing the missing-state snapshot
with the current printer (typically includes
IsOffline: true -> false) - 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();
}Source§impl PrinterMonitor
impl PrinterMonitor
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
- Disappearance fires a synthetic
IsOffline: false -> truechange once per gap - Reappearance fires a change set comparing the missing-state snapshot
with the current printer (typically includes
IsOffline: true -> false) - 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();
}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 fn from_backend(backend: Arc<dyn PrinterBackend>) -> Self
pub fn from_backend(backend: Arc<dyn PrinterBackend>) -> Self
Constructs a monitor around a caller-supplied backend.
Intended for tests and advanced users who need to substitute the
platform backend (e.g. recording, fault injection, scripted
responses for end-to-end change-detection tests). Production code
should use PrinterMonitor::new instead - it auto-selects the
real WMI/CUPS backend for the current platform.
§Example
use std::sync::Arc;
use printer_event_handler::PrinterMonitor;
use printer_event_handler::backend::PrinterBackend;
fn make_monitor(backend: Arc<dyn PrinterBackend>) -> PrinterMonitor {
PrinterMonitor::from_backend(backend)
}Trait Implementations§
Source§impl Clone for PrinterMonitor
impl Clone for PrinterMonitor
Source§fn clone(&self) -> PrinterMonitor
fn clone(&self) -> PrinterMonitor
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more