ipp_proto/operation/
mod.rs1use crate::{attribute::*, ipp::*, request::IppRequestResponse, IppJobSource, IppValue};
5
6pub mod cups;
7
8pub trait IppOperation {
10 fn into_ipp_request(self, uri: &str) -> IppRequestResponse;
12
13 fn version(&self) -> IppVersion {
15 IppVersion::Ipp11
16 }
17}
18
19pub struct PrintJob {
21 source: IppJobSource,
22 user_name: Option<String>,
23 job_name: Option<String>,
24 attributes: Vec<IppAttribute>,
25}
26
27impl PrintJob {
28 pub fn new<U, N>(source: IppJobSource, user_name: Option<U>, job_name: Option<N>) -> PrintJob
34 where
35 U: AsRef<str>,
36 N: AsRef<str>,
37 {
38 PrintJob {
39 source,
40 user_name: user_name.map(|v| v.as_ref().to_string()),
41 job_name: job_name.map(|v| v.as_ref().to_string()),
42 attributes: Vec::new(),
43 }
44 }
45
46 pub fn add_attribute(&mut self, attribute: IppAttribute) {
48 self.attributes.push(attribute);
49 }
50}
51
52impl IppOperation for PrintJob {
53 fn into_ipp_request(self, uri: &str) -> IppRequestResponse {
54 let mut retval = IppRequestResponse::new(self.version(), Operation::PrintJob, Some(uri));
55
56 if let Some(ref user_name) = self.user_name {
57 retval.attributes_mut().add(
58 DelimiterTag::OperationAttributes,
59 IppAttribute::new(REQUESTING_USER_NAME, IppValue::NameWithoutLanguage(user_name.clone())),
60 );
61 }
62
63 if let Some(ref job_name) = self.job_name {
64 retval.attributes_mut().add(
65 DelimiterTag::OperationAttributes,
66 IppAttribute::new(JOB_NAME, IppValue::NameWithoutLanguage(job_name.clone())),
67 )
68 }
69
70 for attr in &self.attributes {
71 retval.attributes_mut().add(DelimiterTag::JobAttributes, attr.clone());
72 }
73 retval.add_payload(self.source);
74 retval
75 }
76}
77
78#[derive(Default)]
80pub struct GetPrinterAttributes {
81 attributes: Vec<String>,
82}
83
84impl GetPrinterAttributes {
85 pub fn new() -> GetPrinterAttributes {
88 GetPrinterAttributes::default()
89 }
90
91 pub fn with_attributes<T>(attributes: &[T]) -> GetPrinterAttributes
93 where
94 T: AsRef<str>,
95 {
96 GetPrinterAttributes {
97 attributes: attributes.iter().map(|a| a.as_ref().to_string()).collect(),
98 }
99 }
100}
101
102impl IppOperation for GetPrinterAttributes {
103 fn into_ipp_request(self, uri: &str) -> IppRequestResponse {
104 let mut retval = IppRequestResponse::new(self.version(), Operation::GetPrinterAttributes, Some(uri));
105
106 if !self.attributes.is_empty() {
107 let vals: Vec<IppValue> = self.attributes.iter().map(|a| IppValue::Keyword(a.clone())).collect();
108 retval.attributes_mut().add(
109 DelimiterTag::OperationAttributes,
110 IppAttribute::new(REQUESTED_ATTRIBUTES, IppValue::ListOf(vals)),
111 );
112 }
113
114 retval
115 }
116}
117
118pub struct CreateJob {
120 job_name: Option<String>,
121 attributes: Vec<IppAttribute>,
122}
123
124impl CreateJob {
125 pub fn new<T>(job_name: Option<T>) -> CreateJob
129 where
130 T: AsRef<str>,
131 {
132 CreateJob {
133 job_name: job_name.map(|v| v.as_ref().to_string()),
134 attributes: Vec::new(),
135 }
136 }
137
138 pub fn add_attribute(&mut self, attribute: IppAttribute) {
140 self.attributes.push(attribute);
141 }
142}
143
144impl IppOperation for CreateJob {
145 fn into_ipp_request(self, uri: &str) -> IppRequestResponse {
146 let mut retval = IppRequestResponse::new(self.version(), Operation::CreateJob, Some(uri));
147
148 if let Some(ref job_name) = self.job_name {
149 retval.attributes_mut().add(
150 DelimiterTag::OperationAttributes,
151 IppAttribute::new(JOB_NAME, IppValue::NameWithoutLanguage(job_name.clone())),
152 )
153 }
154
155 for attr in &self.attributes {
156 retval.attributes_mut().add(DelimiterTag::JobAttributes, attr.clone());
157 }
158 retval
159 }
160}
161
162pub struct SendDocument {
164 job_id: i32,
165 source: IppJobSource,
166 user_name: Option<String>,
167 last: bool,
168}
169
170impl SendDocument {
171 pub fn new<S>(job_id: i32, source: IppJobSource, user_name: Option<S>, last: bool) -> SendDocument
178 where
179 S: AsRef<str>,
180 {
181 SendDocument {
182 job_id,
183 source,
184 user_name: user_name.map(|v| v.as_ref().to_string()),
185 last,
186 }
187 }
188}
189
190impl IppOperation for SendDocument {
191 fn into_ipp_request(self, uri: &str) -> IppRequestResponse {
192 let mut retval = IppRequestResponse::new(self.version(), Operation::SendDocument, Some(uri));
193
194 retval.attributes_mut().add(
195 DelimiterTag::OperationAttributes,
196 IppAttribute::new(JOB_ID, IppValue::Integer(self.job_id)),
197 );
198
199 if let Some(user_name) = self.user_name {
200 retval.attributes_mut().add(
201 DelimiterTag::OperationAttributes,
202 IppAttribute::new(REQUESTING_USER_NAME, IppValue::NameWithoutLanguage(user_name.clone())),
203 );
204 }
205
206 retval.attributes_mut().add(
207 DelimiterTag::OperationAttributes,
208 IppAttribute::new(LAST_DOCUMENT, IppValue::Boolean(self.last)),
209 );
210
211 retval.add_payload(self.source);
212
213 retval
214 }
215}