use ipp::value::{IppKeyword, IppName, IppValue};
use std::collections::BTreeMap;
use super::media_size::MediaSize;
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct MediaInfo {
pub name: Option<IppKeyword>,
pub size: Option<MediaSize>,
pub margins: Option<(i32, i32, i32, i32)>,
pub color: Option<IppKeyword>,
pub source: Option<IppKeyword>,
pub media_type: Option<IppKeyword>,
}
impl MediaInfo {
pub fn name_only(name: IppKeyword) -> Self {
Self {
name: Some(name),
size: None,
margins: None,
color: None,
source: None,
media_type: None,
}
}
}
impl From<BTreeMap<IppName, IppValue>> for MediaInfo {
fn from(collection: BTreeMap<IppName, IppValue>) -> Self {
let size = collection
.get("media-size")
.and_then(|value| value.as_collection())
.map(MediaSize::from);
let top = collection
.get("media-top-margin")
.and_then(|value| value.as_integer().copied());
let right = collection
.get("media-right-margin")
.and_then(|value| value.as_integer().copied());
let bottom = collection
.get("media-bottom-margin")
.and_then(|value| value.as_integer().copied());
let left = collection
.get("media-left-margin")
.and_then(|value| value.as_integer().copied());
let margins = if top.is_some() || right.is_some() || bottom.is_some() || left.is_some() {
Some((
top.unwrap_or(0),
right.unwrap_or(0),
bottom.unwrap_or(0),
left.unwrap_or(0),
))
} else {
None
};
Self {
name: collection
.get("media-size-name")
.and_then(|value| value.as_keyword().cloned()),
size,
margins,
color: collection
.get("media-color")
.and_then(|value| value.as_keyword().cloned()),
source: collection
.get("media-source")
.and_then(|value| value.as_keyword().cloned()),
media_type: collection
.get("media-type")
.and_then(|value| value.as_keyword().cloned()),
}
}
}
impl From<&MediaInfo> for IppValue {
fn from(media: &MediaInfo) -> Self {
let mut collection: BTreeMap<IppName, IppValue> = BTreeMap::new();
if let Some(size) = media.size {
collection.insert("media-size".try_into().unwrap(), IppValue::from(size));
}
if let Some(name) = &media.name {
collection.insert(
"media-size-name".try_into().unwrap(),
IppValue::Keyword(name.clone()),
);
}
if let Some((top, right, bottom, left)) = media.margins {
collection.insert(
"media-top-margin".try_into().unwrap(),
IppValue::Integer(top),
);
collection.insert(
"media-right-margin".try_into().unwrap(),
IppValue::Integer(right),
);
collection.insert(
"media-bottom-margin".try_into().unwrap(),
IppValue::Integer(bottom),
);
collection.insert(
"media-left-margin".try_into().unwrap(),
IppValue::Integer(left),
);
}
if let Some(color) = &media.color {
collection.insert(
"media-color".try_into().unwrap(),
IppValue::Keyword(color.clone()),
);
}
if let Some(source) = &media.source {
collection.insert(
"media-source".try_into().unwrap(),
IppValue::Keyword(source.clone()),
);
}
if let Some(media_type) = &media.media_type {
collection.insert(
"media-type".try_into().unwrap(),
IppValue::Keyword(media_type.clone()),
);
}
IppValue::Collection(collection)
}
}
impl From<MediaInfo> for IppValue {
fn from(media: MediaInfo) -> Self {
Self::from(&media)
}
}