Skip to main content

cpdb_rs/
types.rs

1//! Shared utility types for cpdb-rs.
2
3use std::fmt;
4
5/// The operational state of a printer.
6///
7/// These values map to the IPP `printer-state` attribute, which CPDB
8/// backends (e.g. CUPS) pass through as string literals on D-Bus.
9#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
10#[serde(rename_all = "lowercase")]
11pub enum PrinterState {
12    /// The printer is ready and not currently processing a job.
13    Idle,
14    /// The printer is actively processing a job.
15    Processing,
16    /// The printer queue has been stopped (due to an error, maintenance, or manual pause).
17    Stopped,
18    /// A state string the library doesn't recognize. Preserved for
19    /// forward-compatibility with future or custom CPDB backends.
20    Unknown(String),
21}
22
23impl PrinterState {
24    /// Returns the string representation of the state.
25    pub fn as_str(&self) -> &str {
26        match self {
27            Self::Idle => "idle",
28            Self::Processing => "processing",
29            Self::Stopped => "stopped",
30            Self::Unknown(s) => s.as_str(),
31        }
32    }
33}
34
35impl fmt::Display for PrinterState {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        f.write_str(self.as_str())
38    }
39}
40
41impl From<String> for PrinterState {
42    fn from(s: String) -> Self {
43        match s.as_str() {
44            "idle" => Self::Idle,
45            "processing" => Self::Processing,
46            "stopped" => Self::Stopped,
47            _ => Self::Unknown(s),
48        }
49    }
50}
51
52impl From<&str> for PrinterState {
53    fn from(s: &str) -> Self {
54        match s {
55            "idle" => Self::Idle,
56            "processing" => Self::Processing,
57            "stopped" => Self::Stopped,
58            _ => Self::Unknown(s.to_string()),
59        }
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn test_printer_state_conversions() {
69        assert_eq!(PrinterState::from("idle"), PrinterState::Idle);
70        assert_eq!(PrinterState::from("processing"), PrinterState::Processing);
71        assert_eq!(PrinterState::from("stopped"), PrinterState::Stopped);
72        assert_eq!(
73            PrinterState::from("paused"),
74            PrinterState::Unknown("paused".to_string())
75        );
76
77        assert_eq!(PrinterState::from("idle".to_string()), PrinterState::Idle);
78        assert_eq!(
79            PrinterState::from("testing".to_string()),
80            PrinterState::Unknown("testing".to_string())
81        );
82    }
83
84    #[test]
85    fn test_printer_state_display() {
86        assert_eq!(format!("{}", PrinterState::Idle), "idle");
87        assert_eq!(format!("{}", PrinterState::Processing), "processing");
88        assert_eq!(format!("{}", PrinterState::Stopped), "stopped");
89        assert_eq!(
90            format!("{}", PrinterState::Unknown("offline".to_string())),
91            "offline"
92        );
93    }
94
95    #[test]
96    fn test_printer_state_serde() {
97        let state = PrinterState::Idle;
98        let serialized = serde_json::to_string(&state).unwrap();
99        assert_eq!(serialized, "\"idle\"");
100        let deserialized: PrinterState = serde_json::from_str(&serialized).unwrap();
101        assert_eq!(deserialized, state);
102
103        let custom = PrinterState::Unknown("paused".to_string());
104        let serialized_custom = serde_json::to_string(&custom).unwrap();
105
106        assert_eq!(serialized_custom, "{\"unknown\":\"paused\"}");
107        let deserialized_custom: PrinterState = serde_json::from_str(&serialized_custom).unwrap();
108        assert_eq!(deserialized_custom, custom);
109    }
110}