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)]
139pub enum RenderStep {
140 Types,
142
143 TypesSerdeXmlRs {
145 version: SerdeXmlRsVersion,
147 },
148
149 TypesSerdeQuickXml,
151
152 Defaults,
155
156 NamespaceConstants,
158
159 PrefixConstants,
161
162 WithNamespaceTrait,
165
166 QuickXmlSerialize {
169 namespaces: NamespaceSerialization,
171
172 default_namespace: Option<Namespace>,
174 },
175
176 QuickXmlDeserialize {
179 boxed_deserializer: bool,
183 },
184}
185
186pub trait RenderStepConfig: Debug + Any {
188 fn boxed_clone(&self) -> Box<dyn RenderStepConfig>;
190
191 fn into_render_step(self: Box<Self>) -> Box<dyn RenderStepTrait>;
193
194 fn render_step_type(&self) -> RenderStepType {
196 RenderStepType::Undefined
197 }
198
199 fn is_mutual_exclusive_to(&self, other: &dyn RenderStepConfig) -> bool {
201 self.type_id() == other.type_id()
202 || self
203 .render_step_type()
204 .is_mutual_exclusive_to(other.render_step_type())
205 }
206}
207
208impl<X> RenderStepConfig for X
209where
210 X: RenderStepTrait + Clone + Any + 'static,
211{
212 fn render_step_type(&self) -> RenderStepType {
213 X::render_step_type(self)
214 }
215
216 fn boxed_clone(&self) -> Box<dyn RenderStepConfig> {
217 Box::new(self.clone())
218 }
219
220 fn into_render_step(self: Box<Self>) -> Box<dyn RenderStepTrait> {
221 self
222 }
223}
224
225impl RenderStepConfig for RenderStep {
226 fn render_step_type(&self) -> RenderStepType {
227 match self {
228 Self::Types => RenderStepType::Types,
229 Self::TypesSerdeXmlRs { .. } => RenderStepType::Types,
230 Self::TypesSerdeQuickXml => RenderStepType::Types,
231 Self::Defaults => RenderStepType::ExtraImpls,
232 Self::PrefixConstants => RenderStepType::ExtraImpls,
233 Self::NamespaceConstants => RenderStepType::ExtraImpls,
234 Self::WithNamespaceTrait => RenderStepType::ExtraImpls,
235 Self::QuickXmlSerialize { .. } => RenderStepType::ExtraImpls,
236 Self::QuickXmlDeserialize { .. } => RenderStepType::ExtraImpls,
237 }
238 }
239
240 fn boxed_clone(&self) -> Box<dyn RenderStepConfig> {
241 Box::new(self.clone())
242 }
243
244 fn into_render_step(self: Box<Self>) -> Box<dyn RenderStepTrait> {
245 use crate::pipeline::renderer::{
246 DefaultsRenderStep, NamespaceConstantsRenderStep, PrefixConstantsRenderStep,
247 QuickXmlDeserializeRenderStep, QuickXmlSerializeRenderStep,
248 SerdeQuickXmlTypesRenderStep, SerdeXmlRsV7TypesRenderStep, SerdeXmlRsV8TypesRenderStep,
249 TypesRenderStep, WithNamespaceTraitRenderStep,
250 };
251
252 match *self {
253 Self::Types => Box::new(TypesRenderStep),
254 Self::TypesSerdeXmlRs {
255 version: SerdeXmlRsVersion::Version07AndBelow,
256 } => Box::new(SerdeXmlRsV7TypesRenderStep),
257 Self::TypesSerdeXmlRs {
258 version: SerdeXmlRsVersion::Version08AndAbove,
259 } => Box::new(SerdeXmlRsV8TypesRenderStep),
260 Self::TypesSerdeQuickXml => Box::new(SerdeQuickXmlTypesRenderStep),
261 Self::Defaults => Box::new(DefaultsRenderStep),
262 Self::PrefixConstants => Box::new(PrefixConstantsRenderStep::default()),
263 Self::NamespaceConstants => Box::new(NamespaceConstantsRenderStep::default()),
264 Self::WithNamespaceTrait => Box::new(WithNamespaceTraitRenderStep),
265 Self::QuickXmlSerialize {
266 namespaces,
267 default_namespace,
268 } => Box::new(QuickXmlSerializeRenderStep {
269 namespaces,
270 default_namespace,
271 }),
272 Self::QuickXmlDeserialize { boxed_deserializer } => {
273 Box::new(QuickXmlDeserializeRenderStep { boxed_deserializer })
274 }
275 }
276 }
277
278 fn is_mutual_exclusive_to(&self, other: &dyn RenderStepConfig) -> bool {
279 use crate::pipeline::renderer::{
280 DefaultsRenderStep, NamespaceConstantsRenderStep, QuickXmlDeserializeRenderStep,
281 QuickXmlSerializeRenderStep, SerdeQuickXmlTypesRenderStep, SerdeXmlRsV7TypesRenderStep,
282 SerdeXmlRsV8TypesRenderStep, TypesRenderStep, WithNamespaceTraitRenderStep,
283 };
284
285 if self
286 .render_step_type()
287 .is_mutual_exclusive_to(other.render_step_type())
288 {
289 return true;
290 }
291
292 let other_id = other.type_id();
293 let other = (other as &dyn Any).downcast_ref::<Self>();
294
295 match (self, other) {
296 (Self::Types, Some(Self::Types)) => true,
297 (Self::TypesSerdeXmlRs { .. }, Some(Self::TypesSerdeXmlRs { .. })) => true,
298 (Self::TypesSerdeQuickXml, Some(Self::TypesSerdeQuickXml)) => true,
299 (Self::Defaults, Some(Self::Defaults)) => true,
300 (Self::NamespaceConstants, Some(Self::NamespaceConstants)) => true,
301 (Self::WithNamespaceTrait, Some(Self::WithNamespaceTrait)) => true,
302 (Self::QuickXmlSerialize { .. }, Some(Self::QuickXmlSerialize { .. })) => true,
303 (Self::QuickXmlDeserialize { .. }, Some(Self::QuickXmlDeserialize { .. })) => true,
304 (Self::Types, None) => other_id == TypeId::of::<TypesRenderStep>(),
305 (
306 Self::TypesSerdeXmlRs {
307 version: SerdeXmlRsVersion::Version07AndBelow,
308 },
309 None,
310 ) => other_id == TypeId::of::<SerdeXmlRsV7TypesRenderStep>(),
311 (
312 Self::TypesSerdeXmlRs {
313 version: SerdeXmlRsVersion::Version08AndAbove,
314 },
315 None,
316 ) => other_id == TypeId::of::<SerdeXmlRsV8TypesRenderStep>(),
317 (Self::TypesSerdeQuickXml, None) => {
318 other_id == TypeId::of::<SerdeQuickXmlTypesRenderStep>()
319 }
320 (Self::Defaults, None) => other_id == TypeId::of::<DefaultsRenderStep>(),
321 (Self::NamespaceConstants, None) => {
322 other_id == TypeId::of::<NamespaceConstantsRenderStep>()
323 }
324 (Self::WithNamespaceTrait, None) => {
325 other_id == TypeId::of::<WithNamespaceTraitRenderStep>()
326 }
327 (Self::QuickXmlSerialize { .. }, None) => {
328 other_id == TypeId::of::<QuickXmlSerializeRenderStep>()
329 }
330 (Self::QuickXmlDeserialize { .. }, None) => {
331 other_id == TypeId::of::<QuickXmlDeserializeRenderStep>()
332 }
333 _ => false,
334 }
335 }
336}
337
338impl RenderStep {
339 #[must_use]
341 pub fn is_same(&self, other: &Self) -> bool {
342 match (self, other) {
343 (
344 Self::Types | Self::TypesSerdeXmlRs { .. } | Self::TypesSerdeQuickXml,
345 Self::Types | Self::TypesSerdeXmlRs { .. } | Self::TypesSerdeQuickXml,
346 )
347 | (Self::Defaults, Self::Defaults)
348 | (Self::NamespaceConstants, Self::NamespaceConstants)
349 | (Self::WithNamespaceTrait, Self::WithNamespaceTrait)
350 | (Self::QuickXmlSerialize { .. }, Self::QuickXmlSerialize { .. })
351 | (Self::QuickXmlDeserialize { .. }, Self::QuickXmlDeserialize { .. }) => true,
352 (_, _) => false,
353 }
354 }
355}
356
357#[derive(Debug, Clone, Copy, Eq, PartialEq)]
359pub enum SerdeXmlRsVersion {
360 Version07AndBelow,
362
363 Version08AndAbove,
365}
366
367#[derive(Default, Debug)]
370pub enum DynTypeTraits {
371 #[default]
373 Auto,
374
375 Custom(Vec<IdentPath>),
377}