use crate::{attribute::*, ipp::*, request::IppRequestResponse, IppJobSource, IppValue};
pub mod cups;
pub trait IppOperation {
fn into_ipp_request(self, uri: &str) -> IppRequestResponse;
fn version(&self) -> IppVersion {
IppVersion::Ipp11
}
}
pub struct PrintJob {
source: IppJobSource,
user_name: Option<String>,
job_name: Option<String>,
attributes: Vec<IppAttribute>,
}
impl PrintJob {
pub fn new<U, N>(source: IppJobSource, user_name: Option<U>, job_name: Option<N>) -> PrintJob
where
U: AsRef<str>,
N: AsRef<str>,
{
PrintJob {
source,
user_name: user_name.map(|v| v.as_ref().to_string()),
job_name: job_name.map(|v| v.as_ref().to_string()),
attributes: Vec::new(),
}
}
pub fn add_attribute(&mut self, attribute: IppAttribute) {
self.attributes.push(attribute);
}
}
impl IppOperation for PrintJob {
fn into_ipp_request(self, uri: &str) -> IppRequestResponse {
let mut retval = IppRequestResponse::new(self.version(), Operation::PrintJob, Some(uri));
if let Some(ref user_name) = self.user_name {
retval.attributes_mut().add(
DelimiterTag::OperationAttributes,
IppAttribute::new(REQUESTING_USER_NAME, IppValue::NameWithoutLanguage(user_name.clone())),
);
}
if let Some(ref job_name) = self.job_name {
retval.attributes_mut().add(
DelimiterTag::OperationAttributes,
IppAttribute::new(JOB_NAME, IppValue::NameWithoutLanguage(job_name.clone())),
)
}
for attr in &self.attributes {
retval.attributes_mut().add(DelimiterTag::JobAttributes, attr.clone());
}
retval.add_payload(self.source);
retval
}
}
#[derive(Default)]
pub struct GetPrinterAttributes {
attributes: Vec<String>,
}
impl GetPrinterAttributes {
pub fn new() -> GetPrinterAttributes {
GetPrinterAttributes::default()
}
pub fn with_attributes<T>(attributes: &[T]) -> GetPrinterAttributes
where
T: AsRef<str>,
{
GetPrinterAttributes {
attributes: attributes.iter().map(|a| a.as_ref().to_string()).collect(),
}
}
}
impl IppOperation for GetPrinterAttributes {
fn into_ipp_request(self, uri: &str) -> IppRequestResponse {
let mut retval = IppRequestResponse::new(self.version(), Operation::GetPrinterAttributes, Some(uri));
if !self.attributes.is_empty() {
let vals: Vec<IppValue> = self.attributes.iter().map(|a| IppValue::Keyword(a.clone())).collect();
retval.attributes_mut().add(
DelimiterTag::OperationAttributes,
IppAttribute::new(REQUESTED_ATTRIBUTES, IppValue::ListOf(vals)),
);
}
retval
}
}
pub struct CreateJob {
job_name: Option<String>,
attributes: Vec<IppAttribute>,
}
impl CreateJob {
pub fn new<T>(job_name: Option<T>) -> CreateJob
where
T: AsRef<str>,
{
CreateJob {
job_name: job_name.map(|v| v.as_ref().to_string()),
attributes: Vec::new(),
}
}
pub fn add_attribute(&mut self, attribute: IppAttribute) {
self.attributes.push(attribute);
}
}
impl IppOperation for CreateJob {
fn into_ipp_request(self, uri: &str) -> IppRequestResponse {
let mut retval = IppRequestResponse::new(self.version(), Operation::CreateJob, Some(uri));
if let Some(ref job_name) = self.job_name {
retval.attributes_mut().add(
DelimiterTag::OperationAttributes,
IppAttribute::new(JOB_NAME, IppValue::NameWithoutLanguage(job_name.clone())),
)
}
for attr in &self.attributes {
retval.attributes_mut().add(DelimiterTag::JobAttributes, attr.clone());
}
retval
}
}
pub struct SendDocument {
job_id: i32,
source: IppJobSource,
user_name: Option<String>,
last: bool,
}
impl SendDocument {
pub fn new<S>(job_id: i32, source: IppJobSource, user_name: Option<S>, last: bool) -> SendDocument
where
S: AsRef<str>,
{
SendDocument {
job_id,
source,
user_name: user_name.map(|v| v.as_ref().to_string()),
last,
}
}
}
impl IppOperation for SendDocument {
fn into_ipp_request(self, uri: &str) -> IppRequestResponse {
let mut retval = IppRequestResponse::new(self.version(), Operation::SendDocument, Some(uri));
retval.attributes_mut().add(
DelimiterTag::OperationAttributes,
IppAttribute::new(JOB_ID, IppValue::Integer(self.job_id)),
);
if let Some(user_name) = self.user_name {
retval.attributes_mut().add(
DelimiterTag::OperationAttributes,
IppAttribute::new(REQUESTING_USER_NAME, IppValue::NameWithoutLanguage(user_name.clone())),
);
}
retval.attributes_mut().add(
DelimiterTag::OperationAttributes,
IppAttribute::new(LAST_DOCUMENT, IppValue::Boolean(self.last)),
);
retval.add_payload(self.source);
retval
}
}