1use std::any::{Any, TypeId};
2use std::fmt::Debug;
3
4use bitflags::bitflags;
5
6use crate::models::code::IdentPath;
7use crate::pipeline::renderer::{RenderStep as RenderStepTrait, RenderStepType};
8
9use super::Namespace;
10
11#[derive(Debug)]
13pub struct RendererConfig {
14 pub steps: Vec<Box<dyn RenderStepConfig>>,
16
17 pub flags: RendererFlags,
19
20 pub derive: Option<Vec<String>>,
24
25 pub xsd_parser: String,
27
28 pub dyn_type_traits: Option<Vec<String>>,
32}
33
34impl Default for RendererConfig {
35 fn default() -> Self {
36 Self {
37 steps: vec![Box::new(RenderStep::Types)],
38 flags: RendererFlags::empty(),
39 derive: None,
40 xsd_parser: "xsd_parser".into(),
41 dyn_type_traits: None,
42 }
43 }
44}
45
46impl Clone for RendererConfig {
47 fn clone(&self) -> Self {
48 Self {
49 steps: self.steps.iter().map(|x| x.boxed_clone()).collect(),
50 flags: self.flags,
51 derive: self.derive.clone(),
52 xsd_parser: self.xsd_parser.clone(),
53 dyn_type_traits: self.dyn_type_traits.clone(),
54 }
55 }
56}
57
58bitflags! {
59 #[derive(Debug, Clone, Copy)]
62 pub struct RendererFlags: u32 {
63 #[doc = include_str!("../../tests/renderer/renderer_flags/schema.xsd")]
70 #[doc = include_str!("../../tests/renderer/renderer_flags/expected/empty.rs")]
75 const NONE = 0;
77
78 #[doc = include_str!("../../tests/renderer/renderer_flags/schema_with_docs.xsd")]
86 #[doc = include_str!("../../tests/renderer/renderer_flags/expected/render_docs.rs")]
91 const RENDER_DOCS = Self::RENDER_TYPE_DOCS.bits()
93 | Self::RENDER_ELEMENT_DOCS.bits()
94 | Self::RENDER_ATTRIBUTE_DOCS.bits()
95 | Self::RENDER_VARIANT_DOCS.bits();
96
97 const RENDER_TYPE_DOCS = 1 << 0;
102
103 const RENDER_ELEMENT_DOCS = 1 << 1;
108
109 const RENDER_ATTRIBUTE_DOCS = 1 << 2;
114
115 const RENDER_VARIANT_DOCS = 1 << 3;
121 }
122}
123
124#[derive(Debug, Clone)]
132pub enum RenderStep {
133 Types,
135
136 TypesSerdeXmlRs {
138 version: SerdeXmlRsVersion,
140 },
141
142 TypesSerdeQuickXml,
144
145 Defaults,
148
149 NamespaceConstants,
151
152 WithNamespaceTrait,
155
156 QuickXmlSerialize {
159 with_namespaces: bool,
161
162 default_namespace: Option<Namespace>,
164 },
165
166 QuickXmlDeserialize {
169 boxed_deserializer: bool,
173 },
174}
175
176pub trait RenderStepConfig: Debug + Any {
178 fn boxed_clone(&self) -> Box<dyn RenderStepConfig>;
180
181 fn into_render_step(self: Box<Self>) -> Box<dyn RenderStepTrait>;
183
184 fn render_step_type(&self) -> RenderStepType {
186 RenderStepType::Undefined
187 }
188
189 fn is_mutual_exclusive_to(&self, other: &dyn RenderStepConfig) -> bool {
191 self.type_id() == other.type_id()
192 || self
193 .render_step_type()
194 .is_mutual_exclusive_to(other.render_step_type())
195 }
196}
197
198impl<X> RenderStepConfig for X
199where
200 X: RenderStepTrait + Clone + Any + 'static,
201{
202 fn render_step_type(&self) -> RenderStepType {
203 X::render_step_type(self)
204 }
205
206 fn boxed_clone(&self) -> Box<dyn RenderStepConfig> {
207 Box::new(self.clone())
208 }
209
210 fn into_render_step(self: Box<Self>) -> Box<dyn RenderStepTrait> {
211 self
212 }
213}
214
215impl RenderStepConfig for RenderStep {
216 fn render_step_type(&self) -> RenderStepType {
217 match self {
218 Self::Types => RenderStepType::Types,
219 Self::TypesSerdeXmlRs { .. } => RenderStepType::Types,
220 Self::TypesSerdeQuickXml => RenderStepType::Types,
221 Self::Defaults => RenderStepType::ExtraImpls,
222 Self::NamespaceConstants => RenderStepType::ExtraImpls,
223 Self::WithNamespaceTrait => RenderStepType::ExtraImpls,
224 Self::QuickXmlSerialize { .. } => RenderStepType::ExtraImpls,
225 Self::QuickXmlDeserialize { .. } => RenderStepType::ExtraImpls,
226 }
227 }
228
229 fn boxed_clone(&self) -> Box<dyn RenderStepConfig> {
230 Box::new(self.clone())
231 }
232
233 fn into_render_step(self: Box<Self>) -> Box<dyn RenderStepTrait> {
234 use crate::pipeline::renderer::{
235 DefaultsRenderStep, NamespaceConstantsRenderStep, QuickXmlDeserializeRenderStep,
236 QuickXmlSerializeRenderStep, SerdeQuickXmlTypesRenderStep, SerdeXmlRsV7TypesRenderStep,
237 SerdeXmlRsV8TypesRenderStep, TypesRenderStep, WithNamespaceTraitRenderStep,
238 };
239
240 match *self {
241 Self::Types => Box::new(TypesRenderStep),
242 Self::TypesSerdeXmlRs {
243 version: SerdeXmlRsVersion::Version07AndBelow,
244 } => Box::new(SerdeXmlRsV7TypesRenderStep),
245 Self::TypesSerdeXmlRs {
246 version: SerdeXmlRsVersion::Version08AndAbove,
247 } => Box::new(SerdeXmlRsV8TypesRenderStep),
248 Self::TypesSerdeQuickXml => Box::new(SerdeQuickXmlTypesRenderStep),
249 Self::Defaults => Box::new(DefaultsRenderStep),
250 Self::NamespaceConstants => Box::new(NamespaceConstantsRenderStep::default()),
251 Self::WithNamespaceTrait => Box::new(WithNamespaceTraitRenderStep),
252 Self::QuickXmlSerialize {
253 with_namespaces,
254 default_namespace,
255 } => Box::new(QuickXmlSerializeRenderStep {
256 with_namespaces,
257 default_namespace,
258 }),
259 Self::QuickXmlDeserialize { boxed_deserializer } => {
260 Box::new(QuickXmlDeserializeRenderStep { boxed_deserializer })
261 }
262 }
263 }
264
265 fn is_mutual_exclusive_to(&self, other: &dyn RenderStepConfig) -> bool {
266 use crate::pipeline::renderer::{
267 DefaultsRenderStep, NamespaceConstantsRenderStep, QuickXmlDeserializeRenderStep,
268 QuickXmlSerializeRenderStep, SerdeQuickXmlTypesRenderStep, SerdeXmlRsV7TypesRenderStep,
269 SerdeXmlRsV8TypesRenderStep, TypesRenderStep, WithNamespaceTraitRenderStep,
270 };
271
272 if self
273 .render_step_type()
274 .is_mutual_exclusive_to(other.render_step_type())
275 {
276 return true;
277 }
278
279 let other_id = other.type_id();
280 let other = (other as &dyn Any).downcast_ref::<Self>();
281
282 match (self, other) {
283 (Self::Types, Some(Self::Types)) => true,
284 (Self::TypesSerdeXmlRs { .. }, Some(Self::TypesSerdeXmlRs { .. })) => true,
285 (Self::TypesSerdeQuickXml, Some(Self::TypesSerdeQuickXml)) => true,
286 (Self::Defaults, Some(Self::Defaults)) => true,
287 (Self::NamespaceConstants, Some(Self::NamespaceConstants)) => true,
288 (Self::WithNamespaceTrait, Some(Self::WithNamespaceTrait)) => true,
289 (Self::QuickXmlSerialize { .. }, Some(Self::QuickXmlSerialize { .. })) => true,
290 (Self::QuickXmlDeserialize { .. }, Some(Self::QuickXmlDeserialize { .. })) => true,
291 (Self::Types, None) => other_id == TypeId::of::<TypesRenderStep>(),
292 (
293 Self::TypesSerdeXmlRs {
294 version: SerdeXmlRsVersion::Version07AndBelow,
295 },
296 None,
297 ) => other_id == TypeId::of::<SerdeXmlRsV7TypesRenderStep>(),
298 (
299 Self::TypesSerdeXmlRs {
300 version: SerdeXmlRsVersion::Version08AndAbove,
301 },
302 None,
303 ) => other_id == TypeId::of::<SerdeXmlRsV8TypesRenderStep>(),
304 (Self::TypesSerdeQuickXml, None) => {
305 other_id == TypeId::of::<SerdeQuickXmlTypesRenderStep>()
306 }
307 (Self::Defaults, None) => other_id == TypeId::of::<DefaultsRenderStep>(),
308 (Self::NamespaceConstants, None) => {
309 other_id == TypeId::of::<NamespaceConstantsRenderStep>()
310 }
311 (Self::WithNamespaceTrait, None) => {
312 other_id == TypeId::of::<WithNamespaceTraitRenderStep>()
313 }
314 (Self::QuickXmlSerialize { .. }, None) => {
315 other_id == TypeId::of::<QuickXmlSerializeRenderStep>()
316 }
317 (Self::QuickXmlDeserialize { .. }, None) => {
318 other_id == TypeId::of::<QuickXmlDeserializeRenderStep>()
319 }
320 _ => false,
321 }
322 }
323}
324
325impl RenderStep {
326 #[must_use]
328 pub fn is_same(&self, other: &Self) -> bool {
329 match (self, other) {
330 (
331 Self::Types | Self::TypesSerdeXmlRs { .. } | Self::TypesSerdeQuickXml,
332 Self::Types | Self::TypesSerdeXmlRs { .. } | Self::TypesSerdeQuickXml,
333 )
334 | (Self::Defaults, Self::Defaults)
335 | (Self::NamespaceConstants, Self::NamespaceConstants)
336 | (Self::WithNamespaceTrait, Self::WithNamespaceTrait)
337 | (Self::QuickXmlSerialize { .. }, Self::QuickXmlSerialize { .. })
338 | (Self::QuickXmlDeserialize { .. }, Self::QuickXmlDeserialize { .. }) => true,
339 (_, _) => false,
340 }
341 }
342}
343
344#[derive(Debug, Clone, Copy, Eq, PartialEq)]
346pub enum SerdeXmlRsVersion {
347 Version07AndBelow,
349
350 Version08AndAbove,
352}
353
354#[derive(Default, Debug)]
357pub enum DynTypeTraits {
358 #[default]
360 Auto,
361
362 Custom(Vec<IdentPath>),
364}