xsd_parser/pipeline/renderer/steps/
namespace_const.rs1use std::mem::replace;
2
3use proc_macro2::Literal;
4use quote::quote;
5
6use crate::models::code::IdentPath;
7
8use super::super::{Context, MetaData, Module, RenderStep, RenderStepType};
9
10#[derive(Default, Debug)]
13pub struct NamespaceConstantsRenderStep(State);
14
15#[derive(Default, Debug)]
16enum State {
17 #[default]
18 ResolveNamespace,
19 NamespaceResolved(IdentPath),
20 Done,
21}
22
23impl RenderStep for NamespaceConstantsRenderStep {
24 fn render_step_type(&self) -> RenderStepType {
25 RenderStepType::ExtraImpls
26 }
27
28 fn initialize(&mut self, meta: &mut MetaData<'_>) {
29 if meta.types.meta.types.modules.is_empty() {
30 self.0 = State::Done;
31 }
32 }
33
34 fn render_type(&mut self, ctx: &mut Context<'_, '_>) {
35 if matches!(&self.0, State::ResolveNamespace) {
36 self.0 = State::NamespaceResolved(
37 ctx.resolve_root_ident_path("xsd_parser_types::misc::Namespace"),
38 );
39 }
40 }
41
42 fn finish(&mut self, meta: &MetaData<'_>, module: &mut Module) {
43 let State::NamespaceResolved(namespace) = replace(&mut self.0, State::Done) else {
44 return;
45 };
46
47 let namespace_constants = meta.types.meta.types.modules.values().filter_map(|module| {
48 let ns = module.namespace.as_ref()?;
49 let const_name = module.make_ns_const();
50 let const_name = const_name.path.ident();
51 let ns_literal = Literal::byte_string(&ns.0);
52
53 Some(quote! {
54 pub const #const_name: #namespace = #namespace::new_const(#ns_literal);
55 })
56 });
57
58 module.prepend(quote! { #( #namespace_constants )* });
59 }
60}