use crate::types::PrinterState;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum DiscoveryEvent {
PrinterAdded(PrinterSnapshot),
PrinterRemoved {
id: String,
backend: String,
},
PrinterStateChanged {
id: String,
backend: String,
state: PrinterState,
accepting_jobs: bool,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PrinterSnapshot {
pub id: String,
pub name: String,
pub info: String,
pub location: String,
pub make_model: String,
pub state: PrinterState,
pub accepting_jobs: bool,
pub backend: String,
}
impl PrinterSnapshot {
pub fn is_ready(&self) -> bool {
self.state == PrinterState::Idle && self.accepting_jobs
}
}
impl std::fmt::Display for PrinterSnapshot {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} [{}] ({})", self.name, self.id, self.state)
}
}
#[cfg(test)]
mod tests {
use super::*;
fn sample_snapshot() -> PrinterSnapshot {
PrinterSnapshot {
id: "HP-LaserJet-Pro".to_string(),
name: "HP LaserJet Pro".to_string(),
info: "Office printer".to_string(),
location: "Room 42".to_string(),
make_model: "HP LaserJet Pro MFP".to_string(),
state: PrinterState::Idle,
accepting_jobs: true,
backend: "CUPS".to_string(),
}
}
#[test]
fn snapshot_is_ready_when_idle_and_accepting() {
let snap = sample_snapshot();
assert!(snap.is_ready());
}
#[test]
fn snapshot_not_ready_when_busy() {
let mut snap = sample_snapshot();
snap.state = PrinterState::Processing;
assert!(!snap.is_ready());
}
#[test]
fn snapshot_not_ready_when_not_accepting() {
let mut snap = sample_snapshot();
snap.accepting_jobs = false;
assert!(!snap.is_ready());
}
#[test]
fn snapshot_clones_correctly() {
let snap = sample_snapshot();
let clone = snap.clone();
assert_eq!(snap.id, clone.id);
assert_eq!(snap.backend, clone.backend);
}
#[test]
fn discovery_event_printer_added() {
let event = DiscoveryEvent::PrinterAdded(sample_snapshot());
assert!(matches!(event, DiscoveryEvent::PrinterAdded(_)));
}
#[test]
fn discovery_event_printer_removed() {
let event = DiscoveryEvent::PrinterRemoved {
id: "HP-123".to_string(),
backend: "CUPS".to_string(),
};
match &event {
DiscoveryEvent::PrinterRemoved { id, backend } => {
assert_eq!(id, "HP-123");
assert_eq!(backend, "CUPS");
}
_ => panic!("Expected PrinterRemoved"),
}
}
#[test]
fn discovery_event_state_changed() {
let event = DiscoveryEvent::PrinterStateChanged {
id: "HP-123".to_string(),
backend: "CUPS".to_string(),
state: PrinterState::Processing,
accepting_jobs: true,
};
match &event {
DiscoveryEvent::PrinterStateChanged {
state,
accepting_jobs,
..
} => {
assert_eq!(state, &PrinterState::Processing);
assert!(*accepting_jobs);
}
_ => panic!("Expected PrinterStateChanged"),
}
}
#[test]
fn events_are_clone() {
let event = DiscoveryEvent::PrinterAdded(sample_snapshot());
let clone = event.clone();
assert!(matches!(clone, DiscoveryEvent::PrinterAdded(_)));
}
#[test]
fn snapshot_display() {
let snap = sample_snapshot();
assert_eq!(
format!("{}", snap),
"HP LaserJet Pro [HP-LaserJet-Pro] (idle)"
);
}
#[test]
fn snapshot_equality_and_hashing() {
use std::collections::HashSet;
let snap1 = sample_snapshot();
let snap2 = sample_snapshot();
assert_eq!(snap1, snap2);
let mut set = HashSet::new();
set.insert(snap1.clone());
assert!(set.contains(&snap2));
}
}