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