xsd_parser/pipeline/renderer/steps/
with_namespace_trait.rs1use proc_macro2::{Ident as Ident2, TokenStream};
2use quote::quote;
3
4use crate::config::TypedefMode;
5use crate::models::data::{
6 ComplexData, ComplexDataEnum, ComplexDataStruct, DynamicData, EnumerationData, ReferenceData,
7 SimpleData, UnionData,
8};
9
10use super::super::{Context, DataTypeVariant, RenderStep, RenderStepType};
11
12#[derive(Debug, Clone, Copy)]
15pub struct WithNamespaceTraitRenderStep;
16
17impl RenderStep for WithNamespaceTraitRenderStep {
18 fn render_step_type(&self) -> RenderStepType {
19 RenderStepType::ExtraImpls
20 }
21
22 fn render_type(&mut self, ctx: &mut Context<'_, '_>) {
23 match &ctx.data.variant {
24 DataTypeVariant::BuildIn(_) | DataTypeVariant::Custom(_) => (),
25 DataTypeVariant::Union(x) => x.render_with_namespace_trait(ctx),
26 DataTypeVariant::Dynamic(x) => x.render_with_namespace_trait(ctx),
27 DataTypeVariant::Reference(x) => x.render_with_namespace_trait(ctx),
28 DataTypeVariant::Enumeration(x) => x.render_with_namespace_trait(ctx),
29 DataTypeVariant::Simple(x) => x.render_with_namespace_trait(ctx),
30 DataTypeVariant::Complex(x) => x.render_with_namespace_trait(ctx),
31 }
32 }
33}
34
35impl UnionData<'_> {
38 pub(crate) fn render_with_namespace_trait(&self, ctx: &mut Context<'_, '_>) {
39 if let Some(code) = render_trait_with_namespace(ctx, &self.type_ident) {
40 ctx.current_module().append(code);
41 }
42 }
43}
44
45impl DynamicData<'_> {
48 pub(crate) fn render_with_namespace_trait(&self, ctx: &mut Context<'_, '_>) {
49 if let Some(code) = render_trait_with_namespace(ctx, &self.type_ident) {
50 ctx.current_module().append(code);
51 }
52 }
53}
54
55impl ReferenceData<'_> {
58 pub(crate) fn render_with_namespace_trait(&self, ctx: &mut Context<'_, '_>) {
59 if self.mode == TypedefMode::Typedef {
62 return;
63 }
64
65 if let Some(code) = render_trait_with_namespace(ctx, &self.type_ident) {
66 ctx.current_module().append(code);
67 }
68 }
69}
70
71impl EnumerationData<'_> {
74 pub(crate) fn render_with_namespace_trait(&self, ctx: &mut Context<'_, '_>) {
75 if let Some(code) = render_trait_with_namespace(ctx, &self.type_ident) {
76 ctx.current_module().append(code);
77 }
78 }
79}
80
81impl SimpleData<'_> {
84 pub(crate) fn render_with_namespace_trait(&self, ctx: &mut Context<'_, '_>) {
85 if let Some(code) = render_trait_with_namespace(ctx, &self.type_ident) {
86 ctx.current_module().append(code);
87 }
88 }
89}
90
91impl ComplexData<'_> {
94 pub(crate) fn render_with_namespace_trait(&self, ctx: &mut Context<'_, '_>) {
95 match self {
96 Self::Enum {
97 type_,
98 content_type,
99 } => {
100 type_.render_with_namespace_trait(ctx);
101
102 if let Some(content_type) = content_type {
103 content_type.render_with_namespace_trait(ctx);
104 }
105 }
106 Self::Struct {
107 type_,
108 content_type,
109 } => {
110 type_.render_with_namespace_trait(ctx);
111
112 if let Some(content_type) = content_type {
113 content_type.render_with_namespace_trait(ctx);
114 }
115 }
116 }
117 }
118}
119
120impl ComplexDataEnum<'_> {
121 fn render_with_namespace_trait(&self, ctx: &mut Context<'_, '_>) {
122 if let Some(code) = render_trait_with_namespace(ctx, &self.type_ident) {
123 ctx.current_module().append(code);
124 }
125 }
126}
127
128impl ComplexDataStruct<'_> {
129 fn render_with_namespace_trait(&self, ctx: &mut Context<'_, '_>) {
130 if let Some(code) = render_trait_with_namespace(ctx, &self.type_ident) {
131 ctx.current_module().append(code);
132 }
133 }
134}
135
136fn render_trait_with_namespace(ctx: &Context<'_, '_>, type_ident: &Ident2) -> Option<TokenStream> {
137 let ns = ctx.ident.ns;
138 let module = ctx.types.meta.types.modules.get(&ns)?;
139 let xsd_parser_types = &ctx.xsd_parser_types;
140
141 let (prefix, namespace) = match (&module.prefix, &module.namespace) {
142 (Some(prefix), Some(namespace)) => {
143 let prefix = prefix.as_str();
144 let namespace = namespace.to_string();
145
146 (quote!(Some(#prefix)), quote!(Some(#namespace)))
147 }
148 (None, Some(namespace)) => {
149 let namespace = namespace.to_string();
150
151 (quote!(None), quote!(Some(#namespace)))
152 }
153 (_, None) => (quote!(None), quote!(None)),
154 };
155
156 let str_ = ctx.resolve_build_in("::core::primitive::str");
157 let option = ctx.resolve_build_in("::core::option::Option");
158
159 Some(quote! {
160 impl #xsd_parser_types::WithNamespace for #type_ident {
161 fn prefix() -> #option<&'static #str_> {
162 #prefix
163 }
164
165 fn namespace() -> #option<&'static #str_> {
166 #namespace
167 }
168 }
169 })
170}