1mod generator;
4mod interpreter;
5mod optimizer;
6mod parser;
7mod renderer;
8
9use xsd_parser_types::misc::{Namespace, NamespacePrefix};
10
11pub use crate::models::{meta::MetaType, Ident, IdentType, Name};
12
13use crate::pipeline::renderer::NamespaceSerialization;
14use crate::traits::Naming;
15use crate::InterpreterError;
16
17pub use self::generator::{
18 BoxFlags, Generate, GeneratorConfig, GeneratorFlags, TypePostfix, TypedefMode,
19};
20pub use self::interpreter::{InterpreterConfig, InterpreterFlags};
21pub use self::optimizer::{OptimizerConfig, OptimizerFlags};
22pub use self::parser::{ParserConfig, ParserFlags, Resolver, Schema};
23pub use self::renderer::{
24 DynTypeTraits, RenderStep, RenderStepConfig, RendererConfig, RendererFlags, SerdeXmlRsVersion,
25};
26
27use crate::models::schema::Schemas;
28
29#[must_use]
31#[derive(Default, Debug, Clone)]
32pub struct Config {
33 pub parser: ParserConfig,
35
36 pub interpreter: InterpreterConfig,
38
39 pub optimizer: OptimizerConfig,
41
42 pub generator: GeneratorConfig,
44
45 pub renderer: RendererConfig,
47}
48
49impl Config {
50 pub fn with_schema(mut self, schema: Schema) -> Self {
52 self.parser.schemas.push(schema);
53
54 self
55 }
56
57 pub fn with_schemas<I>(mut self, schemas: I) -> Self
59 where
60 I: IntoIterator<Item = Schema>,
61 {
62 for schema in schemas {
63 self = self.with_schema(schema);
64 }
65
66 self
67 }
68
69 pub fn set_parser_flags(mut self, flags: ParserFlags) -> Self {
71 self.parser.flags = flags;
72
73 self
74 }
75
76 pub fn with_parser_flags(mut self, flags: ParserFlags) -> Self {
78 self.parser.flags.insert(flags);
79
80 self
81 }
82
83 pub fn without_parser_flags(mut self, flags: ParserFlags) -> Self {
85 self.parser.flags.remove(flags);
86
87 self
88 }
89
90 pub fn set_interpreter_flags(mut self, flags: InterpreterFlags) -> Self {
92 self.interpreter.flags = flags;
93
94 self
95 }
96
97 pub fn with_interpreter_flags(mut self, flags: InterpreterFlags) -> Self {
99 self.interpreter.flags.insert(flags);
100
101 self
102 }
103
104 pub fn without_interpreter_flags(mut self, flags: InterpreterFlags) -> Self {
106 self.interpreter.flags.remove(flags);
107
108 self
109 }
110
111 pub fn set_optimizer_flags(mut self, flags: OptimizerFlags) -> Self {
113 self.optimizer.flags = flags;
114
115 self
116 }
117
118 pub fn with_optimizer_flags(mut self, flags: OptimizerFlags) -> Self {
120 self.optimizer.flags.insert(flags);
121
122 self
123 }
124
125 pub fn without_optimizer_flags(mut self, flags: OptimizerFlags) -> Self {
127 self.optimizer.flags.remove(flags);
128
129 self
130 }
131
132 pub fn set_generator_flags(mut self, flags: GeneratorFlags) -> Self {
134 self.generator.flags = flags;
135
136 self
137 }
138
139 pub fn with_generator_flags(mut self, flags: GeneratorFlags) -> Self {
141 self.generator.flags.insert(flags);
142
143 self
144 }
145
146 pub fn without_generator_flags(mut self, flags: GeneratorFlags) -> Self {
148 self.generator.flags.remove(flags);
149
150 self
151 }
152
153 pub fn set_renderer_flags(mut self, flags: RendererFlags) -> Self {
155 self.renderer.flags = flags;
156
157 self
158 }
159
160 pub fn with_renderer_flags(mut self, flags: RendererFlags) -> Self {
162 self.renderer.flags.insert(flags);
163
164 self
165 }
166
167 pub fn without_renderer_flags(mut self, flags: RendererFlags) -> Self {
169 self.renderer.flags.remove(flags);
170
171 self
172 }
173
174 pub fn set_box_flags(mut self, flags: BoxFlags) -> Self {
176 self.generator.box_flags = flags;
177
178 self
179 }
180
181 pub fn with_box_flags(mut self, flags: BoxFlags) -> Self {
183 self.generator.box_flags.insert(flags);
184
185 self
186 }
187
188 pub fn without_box_flags(mut self, flags: BoxFlags) -> Self {
190 self.generator.box_flags.remove(flags);
191
192 self
193 }
194
195 pub fn with_render_step<T>(mut self, step: T) -> Self
200 where
201 T: RenderStepConfig + 'static,
202 {
203 let step = Box::new(step);
204 let mut index = 0;
205 let mut position = None;
206
207 self.renderer.steps.retain(|x| {
209 let mut remove = x.is_mutual_exclusive_to(&*step) || step.is_mutual_exclusive_to(&**x);
210
211 if remove && position.is_none() {
212 remove = false;
213 position = Some(index);
214 }
215
216 index += 1;
217
218 !remove
219 });
220
221 if let Some(pos) = position {
223 self.renderer.steps[pos] = step;
224 } else {
225 self.renderer.steps.push(step);
226 }
227
228 self
229 }
230
231 pub fn with_render_steps<I>(mut self, steps: I) -> Self
235 where
236 I: IntoIterator,
237 I::Item: RenderStepConfig + 'static,
238 {
239 for step in steps {
240 self = self.with_render_step(step);
241 }
242
243 self
244 }
245
246 pub fn with_quick_xml_serialize(self) -> Self {
248 self.with_render_steps([
249 RenderStep::Types,
250 RenderStep::Defaults,
251 RenderStep::PrefixConstants,
252 RenderStep::NamespaceConstants,
253 RenderStep::QuickXmlSerialize {
254 namespaces: NamespaceSerialization::Global,
255 default_namespace: None,
256 },
257 ])
258 }
259
260 pub fn with_quick_xml_serialize_config(
262 mut self,
263 namespaces: NamespaceSerialization,
264 default_namespace: Option<Namespace>,
265 ) -> Self {
266 self = self.with_render_steps([RenderStep::Types, RenderStep::Defaults]);
267
268 if namespaces != NamespaceSerialization::None {
269 self = self.with_render_step(RenderStep::PrefixConstants);
270 }
271
272 self.with_render_steps([
273 RenderStep::NamespaceConstants,
274 RenderStep::QuickXmlSerialize {
275 namespaces,
276 default_namespace,
277 },
278 ])
279 }
280
281 pub fn with_quick_xml_deserialize(self) -> Self {
283 self.with_quick_xml_deserialize_config(false)
284 }
285
286 pub fn with_quick_xml_deserialize_config(self, boxed_deserializer: bool) -> Self {
289 self.with_render_steps([
290 RenderStep::Types,
291 RenderStep::Defaults,
292 RenderStep::NamespaceConstants,
293 RenderStep::QuickXmlDeserialize { boxed_deserializer },
294 ])
295 }
296
297 pub fn with_quick_xml(self) -> Self {
300 self.with_quick_xml_serialize().with_quick_xml_deserialize()
301 }
302
303 pub fn with_quick_xml_config(
306 self,
307 namespace_serialization: NamespaceSerialization,
308 default_serialize_namespace: Option<Namespace>,
309 boxed_deserializer: bool,
310 ) -> Self {
311 self.with_quick_xml_serialize_config(namespace_serialization, default_serialize_namespace)
312 .with_quick_xml_deserialize_config(boxed_deserializer)
313 }
314
315 pub fn with_serde_quick_xml(mut self) -> Self {
317 self.optimizer.flags |= OptimizerFlags::SERDE;
318
319 self.with_render_steps([RenderStep::TypesSerdeQuickXml, RenderStep::Defaults])
320 }
321
322 pub fn with_serde_xml_rs(mut self, version: SerdeXmlRsVersion) -> Self {
324 self.optimizer.flags |= OptimizerFlags::SERDE;
325
326 self.with_render_steps([
327 RenderStep::TypesSerdeXmlRs { version },
328 RenderStep::Defaults,
329 ])
330 }
331
332 pub fn with_generate<I>(mut self, types: I) -> Self
334 where
335 I: IntoIterator,
336 I::Item: Into<IdentTriple>,
337 {
338 self.generator.generate = Generate::Types(types.into_iter().map(Into::into).collect());
339
340 self
341 }
342
343 pub fn with_typedef_mode(mut self, mode: TypedefMode) -> Self {
345 self.generator.typedef_mode = mode;
346
347 self
348 }
349
350 pub fn with_derive<I>(mut self, derive: I) -> Self
352 where
353 I: IntoIterator,
354 I::Item: Into<String>,
355 {
356 self.renderer.derive = Some(
357 derive
358 .into_iter()
359 .map(Into::into)
360 .filter(|s| !s.is_empty())
361 .collect(),
362 );
363
364 self
365 }
366
367 pub fn with_any_type_support(self) -> Self {
369 self.with_generator_flags(GeneratorFlags::ANY_TYPE_SUPPORT)
370 }
371
372 pub fn with_any_types<S, T>(mut self, any_type: S, any_attributes_type: T) -> Self
374 where
375 S: Into<String>,
376 T: Into<String>,
377 {
378 self.generator.any_type = any_type.into();
379 self.generator.any_attributes_type = any_attributes_type.into();
380
381 self.with_any_type_support()
382 }
383
384 pub fn with_mixed_type_support(self) -> Self {
386 self.with_generator_flags(GeneratorFlags::MIXED_TYPE_SUPPORT)
387 }
388
389 pub fn with_mixed_types<S, T>(mut self, text_type: S, mixed_type: T) -> Self
391 where
392 S: Into<String>,
393 T: Into<String>,
394 {
395 self.generator.text_type = text_type.into();
396 self.generator.mixed_type = mixed_type.into();
397
398 self.with_mixed_type_support()
399 }
400
401 pub fn with_nillable_type_support(self) -> Self {
403 self.with_generator_flags(GeneratorFlags::NILLABLE_TYPE_SUPPORT)
404 }
405
406 pub fn with_nillable_type<S>(mut self, nillable_type: S) -> Self
408 where
409 S: Into<String>,
410 {
411 self.generator.nillable_type = nillable_type.into();
412
413 self.with_nillable_type_support()
414 }
415
416 pub fn with_naming<X>(mut self, naming: X) -> Self
418 where
419 X: Naming + 'static,
420 {
421 self.interpreter.naming = Some(Box::new(naming));
422
423 self
424 }
425}
426
427#[derive(Debug, Clone)]
438pub struct IdentTriple {
439 pub ns: Option<NamespaceIdent>,
441
442 pub name: String,
444
445 pub type_: IdentType,
447}
448
449impl IdentTriple {
450 pub fn resolve(self, schemas: &Schemas) -> Result<Ident, InterpreterError> {
457 let ns = match self.ns {
458 None => None,
459 Some(NamespaceIdent::Prefix(prefix)) => Some(
460 schemas
461 .resolve_prefix(&prefix)
462 .ok_or(InterpreterError::UnknownNamespacePrefix(prefix))?,
463 ),
464 #[allow(clippy::unnecessary_literal_unwrap)]
465 Some(NamespaceIdent::Namespace(ns)) => {
466 let ns = Some(ns);
467 Some(
468 schemas
469 .resolve_namespace(&ns)
470 .ok_or_else(|| InterpreterError::UnknownNamespace(ns.unwrap()))?,
471 )
472 }
473 };
474
475 Ok(Ident {
476 ns,
477 name: Name::new_named(self.name),
478 type_: self.type_,
479 })
480 }
481}
482
483impl<X> From<(IdentType, X)> for IdentTriple
484where
485 X: AsRef<str>,
486{
487 fn from((type_, ident): (IdentType, X)) -> Self {
488 let ident = ident.as_ref();
489 let (prefix, name) = ident
490 .split_once(':')
491 .map_or((None, ident), |(a, b)| (Some(a), b));
492 let ns = prefix.map(|x| NamespaceIdent::prefix(x.as_bytes().to_owned()));
493 let name = name.to_owned();
494
495 Self { ns, name, type_ }
496 }
497}
498
499impl<N, X> From<(IdentType, N, X)> for IdentTriple
500where
501 N: Into<Option<NamespaceIdent>>,
502 X: Into<String>,
503{
504 fn from((type_, ns, name): (IdentType, N, X)) -> Self {
505 let ns = ns.into();
506 let name = name.into();
507
508 Self { ns, name, type_ }
509 }
510}
511
512#[derive(Debug, Clone)]
514pub enum NamespaceIdent {
515 Prefix(NamespacePrefix),
517
518 Namespace(Namespace),
520}
521
522impl NamespaceIdent {
523 pub fn prefix<X>(value: X) -> Self
525 where
526 NamespacePrefix: From<X>,
527 {
528 Self::Prefix(NamespacePrefix::from(value))
529 }
530
531 pub fn namespace<X>(value: X) -> Self
533 where
534 Namespace: From<X>,
535 {
536 Self::Namespace(Namespace::from(value))
537 }
538}
539
540impl From<Namespace> for NamespaceIdent {
541 fn from(value: Namespace) -> Self {
542 Self::Namespace(value)
543 }
544}
545
546impl From<NamespacePrefix> for NamespaceIdent {
547 fn from(value: NamespacePrefix) -> Self {
548 Self::Prefix(value)
549 }
550}