xsd_parser/generator/renderer/
defaults.rs

1use proc_macro2::TokenStream;
2use quote::{format_ident, quote};
3
4use crate::generator::data::{ComplexType, ComplexTypeAttribute, ComplexTypeStruct};
5
6use super::{Context, Renderer, TypeData};
7
8/// Implements a [`Renderer`] that renders associated methods that return the default
9/// values of the different attributes and elements according to the schema.
10#[derive(Debug)]
11pub struct DefaultsRenderer;
12
13impl Renderer for DefaultsRenderer {
14    fn render_type(&mut self, ctx: &mut Context<'_, '_>, ty: &TypeData<'_>) {
15        if let TypeData::Complex(x) = ty {
16            x.render_defaults(ctx);
17        }
18    }
19}
20
21/* ComplexType */
22
23impl ComplexType<'_> {
24    pub(crate) fn render_defaults(&self, ctx: &mut Context<'_, '_>) {
25        match self {
26            ComplexType::Enum {
27                type_: _,
28                content_type,
29            } => {
30                if let Some(content_type) = content_type {
31                    content_type.render_defaults(ctx);
32                }
33            }
34            ComplexType::Struct {
35                type_,
36                content_type,
37            } => {
38                type_.render_defaults(ctx);
39
40                if let Some(content_type) = content_type {
41                    content_type.render_defaults(ctx);
42                }
43            }
44        }
45    }
46}
47
48impl ComplexTypeStruct<'_> {
49    pub(crate) fn render_defaults(&self, ctx: &mut Context<'_, '_>) {
50        let type_ident = &self.type_ident;
51        let mut has_attributes = false;
52        let attribute_defaults = self
53            .attributes
54            .iter()
55            .filter_map(ComplexTypeAttribute::render_default_fn)
56            .inspect(|_| has_attributes = true);
57
58        let impl_ = quote! {
59            impl #type_ident {
60                #( #attribute_defaults )*
61            }
62        };
63
64        if has_attributes {
65            ctx.module().append(impl_);
66        }
67    }
68}
69
70impl ComplexTypeAttribute<'_> {
71    fn render_default_fn(&self) -> Option<TokenStream> {
72        let default = self.default_value.as_ref()?;
73        let target_type = self.target_type.ident();
74        let default_fn_ident = format_ident!("default_{}", self.ident);
75
76        Some(quote! {
77            #[must_use]
78            pub fn #default_fn_ident() -> #target_type {
79                #default
80            }
81        })
82    }
83}