winprint_ext/ticket/
feature_option_pack.rs1use xml::name::OwnedName;
2
3use super::{
4 document::{
5 ParameterInit, PrintFeature, PrintFeatureOption, PrintTicketDocument, WithProperties,
6 NS_PSK,
7 },
8 PrintCapabilities, PrintTicket,
9};
10
11pub trait PredefinedName: Sized {
13 fn from_name(name: &OwnedName) -> Option<Self>;
16}
17
18pub trait FeatureOptionPack: Sized {
20 fn new(option: PrintFeatureOption, parameters: Vec<ParameterInit>) -> Self;
22
23 fn feature_name() -> OwnedName;
25
26 fn option(&self) -> &PrintFeatureOption;
28 fn option_mut(&mut self) -> &mut PrintFeatureOption;
30
31 fn parameters(&self) -> &[ParameterInit];
33 fn parameters_mut(&mut self) -> &mut Vec<ParameterInit>;
35
36 fn into_option_with_parameters(self) -> (PrintFeatureOption, Vec<ParameterInit>);
38
39 fn display_name(&self) -> Option<&str> {
41 self.option()
42 .get_property("DisplayName", Some(NS_PSK))
43 .and_then(|x| x.value.as_ref())
44 .and_then(|x| x.string())
45 }
46
47 fn list(capabilities: &PrintCapabilities) -> impl Iterator<Item = Self> + '_ {
49 capabilities
50 .options_for_feature(Self::feature_name())
51 .map(move |option| {
52 let default_parameters = capabilities
53 .default_parameters_for(option.parameters_dependent().as_slice())
54 .collect();
55 Self::new(option.clone(), default_parameters)
56 })
57 }
58}
59
60impl<T> From<T> for PrintTicket
61where
62 T: FeatureOptionPack,
63{
64 fn from(value: T) -> Self {
65 let (option, parameters) = value.into_option_with_parameters();
66 PrintTicketDocument {
67 properties: vec![],
68 parameter_inits: parameters,
69 features: vec![PrintFeature {
70 name: T::feature_name(),
71 properties: vec![],
72 options: vec![option],
73 features: vec![],
74 }],
75 }
76 .into()
77 }
78}
79
80pub trait FeatureOptionPackWithPredefined: FeatureOptionPack {
82 type PredefinedName: PredefinedName;
84
85 fn as_predefined_name(&self) -> Option<Self::PredefinedName> {
88 self.option()
89 .name
90 .as_ref()
91 .and_then(Self::PredefinedName::from_name)
92 }
93}
94
95macro_rules! define_feature_option_pack {
111 ($feature_name:expr, $name:ident) => {
112 #[derive(Clone, Debug)]
113 #[doc = concat!("Represents a feature option pack as [`", stringify!($name), "`].")]
114 pub struct $name {
115 option: PrintFeatureOption,
117 parameters: Vec<ParameterInit>,
119 }
120
121 impl crate::ticket::FeatureOptionPack for $name {
122 fn new(option: PrintFeatureOption, parameters: Vec<ParameterInit>) -> Self {
123 Self { option, parameters }
124 }
125
126 fn feature_name() -> OwnedName {
127 $feature_name
128 }
129
130 fn option(&self) -> &PrintFeatureOption {
131 &self.option
132 }
133
134 fn option_mut(&mut self) -> &mut PrintFeatureOption {
135 &mut self.option
136 }
137
138 fn parameters(&self) -> &[ParameterInit] {
139 &self.parameters
140 }
141
142 fn parameters_mut(&mut self) -> &mut Vec<ParameterInit> {
143 &mut self.parameters
144 }
145
146 fn into_option_with_parameters(self) -> (PrintFeatureOption, Vec<ParameterInit>) {
147 (self.option, self.parameters)
148 }
149 }
150 };
151 ($feature_name:expr, $name:ident, $predefined_name:ident) => {
152 define_feature_option_pack!($feature_name, $name);
153
154 impl crate::ticket::FeatureOptionPackWithPredefined for $name {
155 type PredefinedName = $predefined_name;
156 }
157 };
158}
159pub(crate) use define_feature_option_pack;