ipp_printer_app/
printer.rs1use std::sync::Arc;
4
5use parking_lot::RwLock;
6
7use crate::flags::PrinterReason;
8
9#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
13#[allow(missing_docs)]
14pub struct PrinterConfig {
15 pub name: String,
16 pub driver_name: String,
17 pub make_and_model: String,
18 pub device_id: String,
19 pub device_uri: String,
20 pub dpi: i32,
21 pub printhead_width_dots: u32,
22 pub media_names: Vec<String>,
23 pub media_sizes: Vec<[i32; 2]>,
24 pub darkness: i32,
26 #[serde(default)]
32 pub document_formats: Vec<String>,
33}
34
35impl PrinterConfig {
36 pub fn printer_uri(&self, host: &str, port: u16) -> String {
40 let h = if host == "0.0.0.0" || host == "::" || host.is_empty() {
41 "localhost"
42 } else {
43 host
44 };
45 format!("ipp://{h}:{port}/ipp/print/{}", self.name)
46 }
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq)]
51#[repr(u32)]
52#[allow(missing_docs)]
53pub enum IppPrinterState {
54 Idle = 3,
55 Processing = 4,
56 Stopped = 5,
57}
58
59#[derive(Debug, Clone)]
61#[allow(missing_docs)]
62pub struct PrinterRecord {
63 pub config: PrinterConfig,
64 pub state: IppPrinterState,
65 pub reasons: PrinterReason,
66 pub uuid: String,
67 pub ready_media: Option<crate::device::ReadyMedia>,
71 pub supply_percent: Option<u8>,
74}
75
76impl PrinterRecord {
77 pub fn new(config: PrinterConfig) -> Self {
79 Self {
80 uuid: uuid::Uuid::new_v4().to_string(),
81 state: IppPrinterState::Idle,
82 reasons: PrinterReason::empty(),
83 ready_media: None,
84 supply_percent: None,
85 config,
86 }
87 }
88}
89
90pub struct PrinterHandle<'a> {
95 pub record: &'a PrinterRecord,
97}
98
99impl<'a> PrinterHandle<'a> {
100 pub fn driver_name(&self) -> &str {
103 &self.record.config.driver_name
104 }
105
106 pub fn darkness(&self) -> i32 {
108 self.record.config.darkness
109 }
110
111 pub fn printhead_width_dots(&self) -> u32 {
113 self.record.config.printhead_width_dots
114 }
115}
116
117pub type PrinterRegistry = Arc<RwLock<Vec<PrinterRecord>>>;
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
127 fn config_without_document_formats_loads() {
128 let json = r#"{
129 "name": "p", "driver_name": "d", "make_and_model": "m",
130 "device_id": "", "device_uri": "mock://x", "dpi": 203,
131 "printhead_width_dots": 384, "media_names": [], "media_sizes": [],
132 "darkness": 50
133 }"#;
134 let cfg: PrinterConfig = serde_json::from_str(json).expect("back-compat load");
135 assert!(cfg.document_formats.is_empty());
136 }
137}