use xml::name::OwnedName;
use super::{
document::{
ParameterInit, PrintFeature, PrintFeatureOption, PrintTicketDocument, WithProperties,
NS_PSK,
},
PrintCapabilities, PrintTicket,
};
pub trait PredefinedName: Sized {
fn from_name(name: &OwnedName) -> Option<Self>;
}
pub trait FeatureOptionPack: Sized {
fn new(option: PrintFeatureOption, parameters: Vec<ParameterInit>) -> Self;
fn feature_name() -> OwnedName;
fn option(&self) -> &PrintFeatureOption;
fn option_mut(&mut self) -> &mut PrintFeatureOption;
fn parameters(&self) -> &[ParameterInit];
fn parameters_mut(&mut self) -> &mut Vec<ParameterInit>;
fn into_option_with_parameters(self) -> (PrintFeatureOption, Vec<ParameterInit>);
fn display_name(&self) -> Option<&str> {
self.option()
.get_property("DisplayName", Some(NS_PSK))
.and_then(|x| x.value.as_ref())
.and_then(|x| x.string())
}
fn list(capabilities: &PrintCapabilities) -> impl Iterator<Item = Self> + '_ {
capabilities
.options_for_feature(Self::feature_name())
.map(move |option| {
let default_parameters = capabilities
.default_parameters_for(option.parameters_dependent().as_slice())
.collect();
Self::new(option.clone(), default_parameters)
})
}
}
impl<T> From<T> for PrintTicket
where
T: FeatureOptionPack,
{
fn from(value: T) -> Self {
let (option, parameters) = value.into_option_with_parameters();
PrintTicketDocument {
properties: vec![],
parameter_inits: parameters,
features: vec![PrintFeature {
name: T::feature_name(),
properties: vec![],
options: vec![option],
features: vec![],
}],
}
.into()
}
}
pub trait FeatureOptionPackWithPredefined: FeatureOptionPack {
type PredefinedName: PredefinedName;
fn as_predefined_name(&self) -> Option<Self::PredefinedName> {
self.option()
.name
.as_ref()
.and_then(Self::PredefinedName::from_name)
}
}
macro_rules! define_feature_option_pack {
($feature_name:expr, $name:ident) => {
#[derive(Clone, Debug)]
#[doc = concat!("Represents a feature option pack as [`", stringify!($name), "`].")]
pub struct $name {
/// The option of the feature.
option: PrintFeatureOption,
parameters: Vec<ParameterInit>,
}
impl crate::ticket::FeatureOptionPack for $name {
fn new(option: PrintFeatureOption, parameters: Vec<ParameterInit>) -> Self {
Self { option, parameters }
}
fn feature_name() -> OwnedName {
$feature_name
}
fn option(&self) -> &PrintFeatureOption {
&self.option
}
fn option_mut(&mut self) -> &mut PrintFeatureOption {
&mut self.option
}
fn parameters(&self) -> &[ParameterInit] {
&self.parameters
}
fn parameters_mut(&mut self) -> &mut Vec<ParameterInit> {
&mut self.parameters
}
fn into_option_with_parameters(self) -> (PrintFeatureOption, Vec<ParameterInit>) {
(self.option, self.parameters)
}
}
};
($feature_name:expr, $name:ident, $predefined_name:ident) => {
define_feature_option_pack!($feature_name, $name);
impl crate::ticket::FeatureOptionPackWithPredefined for $name {
type PredefinedName = $predefined_name;
}
};
}
pub(crate) use define_feature_option_pack;