1use std::any::{Any, TypeId};
2use std::fmt::Debug;
3
4use bitflags::bitflags;
5
6use xsd_parser_types::misc::Namespace;
7
8use crate::models::code::IdentPath;
9use crate::pipeline::renderer::{
10 NamespaceSerialization, RenderStep as RenderStepTrait, RenderStepType,
11};
12
13#[derive(Debug)]
15pub struct RendererConfig {
16 pub steps: Vec<Box<dyn RenderStepConfig>>,
18
19 pub flags: RendererFlags,
21
22 pub derive: Option<Vec<String>>,
26
27 pub alloc: String,
29
30 pub dyn_type_traits: Option<Vec<String>>,
34
35 pub xsd_parser_types: String,
37}
38
39impl Default for RendererConfig {
40 fn default() -> Self {
41 Self {
42 steps: vec![Box::new(RenderStep::Types)],
43 flags: RendererFlags::empty(),
44 derive: None,
45 alloc: "std".into(),
46 dyn_type_traits: None,
47 xsd_parser_types: "xsd_parser_types".into(),
48 }
49 }
50}
51
52impl Clone for RendererConfig {
53 fn clone(&self) -> Self {
54 Self {
55 steps: self.steps.iter().map(|x| x.boxed_clone()).collect(),
56 flags: self.flags,
57 derive: self.derive.clone(),
58 alloc: self.alloc.clone(),
59 dyn_type_traits: self.dyn_type_traits.clone(),
60 xsd_parser_types: self.xsd_parser_types.clone(),
61 }
62 }
63}
64
65bitflags! {
66 #[derive(Debug, Clone, Copy)]
69 pub struct RendererFlags: u32 {
70 #[doc = include_str!("../../tests/renderer/renderer_flags/schema.xsd")]
77 #[doc = include_str!("../../tests/renderer/renderer_flags/expected/empty.rs")]
82 const NONE = 0;
84
85 #[doc = include_str!("../../tests/renderer/renderer_flags/schema_with_docs.xsd")]
93 #[doc = include_str!("../../tests/renderer/renderer_flags/expected/render_docs.rs")]
98 const RENDER_DOCS = Self::RENDER_TYPE_DOCS.bits()
100 | Self::RENDER_ELEMENT_DOCS.bits()
101 | Self::RENDER_ATTRIBUTE_DOCS.bits()
102 | Self::RENDER_VARIANT_DOCS.bits();
103
104 const RENDER_TYPE_DOCS = 1 << 0;
109
110 const RENDER_ELEMENT_DOCS = 1 << 1;
115
116 const RENDER_ATTRIBUTE_DOCS = 1 << 2;
121
122 const RENDER_VARIANT_DOCS = 1 << 3;
128 }
129}
130
131#[derive(Debug, Clone)]
142pub enum RenderStep {
143 Types,
145
146 TypesSerdeXmlRs {
148 version: SerdeXmlRsVersion,
150 },
151
152 TypesSerdeQuickXml,
154
155 Defaults,
158
159 NamespaceConstants,
161
162 EnumConstants,
164
165 PrefixConstants,
167
168 WithNamespaceTrait,
171
172 QuickXmlSerialize {
175 namespaces: NamespaceSerialization,
177
178 default_namespace: Option<Namespace>,
180 },
181
182 QuickXmlDeserialize {
185 boxed_deserializer: bool,
189 },
190
191 QuickXmlCollectNamespaces,
198}
199
200pub trait RenderStepConfig: Debug + Any {
202 fn boxed_clone(&self) -> Box<dyn RenderStepConfig>;
204
205 fn into_render_step(self: Box<Self>) -> Box<dyn RenderStepTrait>;
207
208 fn render_step_type(&self) -> RenderStepType {
210 RenderStepType::Undefined
211 }
212
213 fn is_mutual_exclusive_to(&self, other: &dyn RenderStepConfig) -> bool {
215 self.type_id() == other.type_id()
216 || self
217 .render_step_type()
218 .is_mutual_exclusive_to(other.render_step_type())
219 }
220}
221
222impl<X> RenderStepConfig for X
223where
224 X: RenderStepTrait + Clone + Any + 'static,
225{
226 fn render_step_type(&self) -> RenderStepType {
227 X::render_step_type(self)
228 }
229
230 fn boxed_clone(&self) -> Box<dyn RenderStepConfig> {
231 Box::new(self.clone())
232 }
233
234 fn into_render_step(self: Box<Self>) -> Box<dyn RenderStepTrait> {
235 self
236 }
237}
238
239impl RenderStepConfig for RenderStep {
240 fn render_step_type(&self) -> RenderStepType {
241 match self {
242 Self::Types => RenderStepType::Types,
243 Self::TypesSerdeXmlRs { .. } => RenderStepType::Types,
244 Self::TypesSerdeQuickXml => RenderStepType::Types,
245 Self::Defaults => RenderStepType::ExtraImpls,
246 Self::EnumConstants => RenderStepType::ExtraImpls,
247 Self::PrefixConstants => RenderStepType::ExtraImpls,
248 Self::NamespaceConstants => RenderStepType::ExtraImpls,
249 Self::WithNamespaceTrait => RenderStepType::ExtraImpls,
250 Self::QuickXmlSerialize { .. } => RenderStepType::ExtraImpls,
251 Self::QuickXmlDeserialize { .. } => RenderStepType::ExtraImpls,
252 Self::QuickXmlCollectNamespaces => RenderStepType::ExtraImpls,
253 }
254 }
255
256 fn boxed_clone(&self) -> Box<dyn RenderStepConfig> {
257 Box::new(self.clone())
258 }
259
260 fn into_render_step(self: Box<Self>) -> Box<dyn RenderStepTrait> {
261 use crate::pipeline::renderer::{
262 DefaultsRenderStep, EnumConstantsRenderStep, NamespaceConstantsRenderStep,
263 PrefixConstantsRenderStep, QuickXmlCollectNamespacesRenderStep,
264 QuickXmlDeserializeRenderStep, QuickXmlSerializeRenderStep,
265 SerdeQuickXmlTypesRenderStep, SerdeXmlRsV7TypesRenderStep, SerdeXmlRsV8TypesRenderStep,
266 TypesRenderStep, WithNamespaceTraitRenderStep,
267 };
268
269 match *self {
270 Self::Types => Box::new(TypesRenderStep),
271 Self::TypesSerdeXmlRs {
272 version: SerdeXmlRsVersion::Version07AndBelow,
273 } => Box::new(SerdeXmlRsV7TypesRenderStep),
274 Self::TypesSerdeXmlRs {
275 version: SerdeXmlRsVersion::Version08AndAbove,
276 } => Box::new(SerdeXmlRsV8TypesRenderStep),
277 Self::TypesSerdeQuickXml => Box::new(SerdeQuickXmlTypesRenderStep),
278 Self::Defaults => Box::new(DefaultsRenderStep),
279 Self::EnumConstants => Box::new(EnumConstantsRenderStep),
280 Self::PrefixConstants => Box::new(PrefixConstantsRenderStep::default()),
281 Self::NamespaceConstants => Box::new(NamespaceConstantsRenderStep::default()),
282 Self::WithNamespaceTrait => Box::new(WithNamespaceTraitRenderStep),
283 Self::QuickXmlSerialize {
284 namespaces,
285 default_namespace,
286 } => Box::new(QuickXmlSerializeRenderStep {
287 namespaces,
288 default_namespace,
289 }),
290 Self::QuickXmlDeserialize { boxed_deserializer } => {
291 Box::new(QuickXmlDeserializeRenderStep { boxed_deserializer })
292 }
293 Self::QuickXmlCollectNamespaces => Box::new(QuickXmlCollectNamespacesRenderStep),
294 }
295 }
296
297 fn is_mutual_exclusive_to(&self, other: &dyn RenderStepConfig) -> bool {
298 use crate::pipeline::renderer::{
299 DefaultsRenderStep, NamespaceConstantsRenderStep, QuickXmlCollectNamespacesRenderStep,
300 QuickXmlDeserializeRenderStep, QuickXmlSerializeRenderStep,
301 SerdeQuickXmlTypesRenderStep, SerdeXmlRsV7TypesRenderStep, SerdeXmlRsV8TypesRenderStep,
302 TypesRenderStep, WithNamespaceTraitRenderStep,
303 };
304
305 if self
306 .render_step_type()
307 .is_mutual_exclusive_to(other.render_step_type())
308 {
309 return true;
310 }
311
312 let other_id = other.type_id();
313 let other = (other as &dyn Any).downcast_ref::<Self>();
314
315 match (self, other) {
316 (Self::Types, Some(Self::Types)) => true,
317 (Self::TypesSerdeXmlRs { .. }, Some(Self::TypesSerdeXmlRs { .. })) => true,
318 (Self::TypesSerdeQuickXml, Some(Self::TypesSerdeQuickXml)) => true,
319 (Self::Defaults, Some(Self::Defaults)) => true,
320 (Self::NamespaceConstants, Some(Self::NamespaceConstants)) => true,
321 (Self::WithNamespaceTrait, Some(Self::WithNamespaceTrait)) => true,
322 (Self::QuickXmlSerialize { .. }, Some(Self::QuickXmlSerialize { .. })) => true,
323 (Self::QuickXmlDeserialize { .. }, Some(Self::QuickXmlDeserialize { .. })) => true,
324 (Self::QuickXmlCollectNamespaces, Some(Self::QuickXmlCollectNamespaces)) => true,
325 (Self::Types, None) => other_id == TypeId::of::<TypesRenderStep>(),
326 (
327 Self::TypesSerdeXmlRs {
328 version: SerdeXmlRsVersion::Version07AndBelow,
329 },
330 None,
331 ) => other_id == TypeId::of::<SerdeXmlRsV7TypesRenderStep>(),
332 (
333 Self::TypesSerdeXmlRs {
334 version: SerdeXmlRsVersion::Version08AndAbove,
335 },
336 None,
337 ) => other_id == TypeId::of::<SerdeXmlRsV8TypesRenderStep>(),
338 (Self::TypesSerdeQuickXml, None) => {
339 other_id == TypeId::of::<SerdeQuickXmlTypesRenderStep>()
340 }
341 (Self::Defaults, None) => other_id == TypeId::of::<DefaultsRenderStep>(),
342 (Self::NamespaceConstants, None) => {
343 other_id == TypeId::of::<NamespaceConstantsRenderStep>()
344 }
345 (Self::WithNamespaceTrait, None) => {
346 other_id == TypeId::of::<WithNamespaceTraitRenderStep>()
347 }
348 (Self::QuickXmlSerialize { .. }, None) => {
349 other_id == TypeId::of::<QuickXmlSerializeRenderStep>()
350 }
351 (Self::QuickXmlDeserialize { .. }, None) => {
352 other_id == TypeId::of::<QuickXmlDeserializeRenderStep>()
353 }
354 (Self::QuickXmlCollectNamespaces, None) => {
355 other_id == TypeId::of::<QuickXmlCollectNamespacesRenderStep>()
356 }
357 _ => false,
358 }
359 }
360}
361
362impl RenderStep {
363 #[must_use]
365 pub fn is_same(&self, other: &Self) -> bool {
366 match (self, other) {
367 (
368 Self::Types | Self::TypesSerdeXmlRs { .. } | Self::TypesSerdeQuickXml,
369 Self::Types | Self::TypesSerdeXmlRs { .. } | Self::TypesSerdeQuickXml,
370 )
371 | (Self::Defaults, Self::Defaults)
372 | (Self::NamespaceConstants, Self::NamespaceConstants)
373 | (Self::WithNamespaceTrait, Self::WithNamespaceTrait)
374 | (Self::QuickXmlSerialize { .. }, Self::QuickXmlSerialize { .. })
375 | (Self::QuickXmlDeserialize { .. }, Self::QuickXmlDeserialize { .. })
376 | (Self::QuickXmlCollectNamespaces, Self::QuickXmlCollectNamespaces) => true,
377 (_, _) => false,
378 }
379 }
380}
381
382#[derive(Debug, Clone, Copy, Eq, PartialEq)]
384pub enum SerdeXmlRsVersion {
385 Version07AndBelow,
387
388 Version08AndAbove,
390}
391
392#[derive(Default, Debug)]
395pub enum DynTypeTraits {
396 #[default]
398 Auto,
399
400 Custom(Vec<IdentPath>),
402}