xsd_parser/pipeline/renderer/steps/
prefix_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 PrefixConstantsRenderStep(State);
14
15#[derive(Default, Debug)]
16enum State {
17 #[default]
18 ResolveNamespace,
19 NamespaceResolved(IdentPath),
20 Done,
21}
22
23impl RenderStep for PrefixConstantsRenderStep {
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::NamespacePrefix"),
38 );
39 }
40 }
41
42 fn finish(&mut self, meta: &MetaData<'_>, module: &mut Module) {
43 let State::NamespaceResolved(prefix) = replace(&mut self.0, State::Done) else {
44 return;
45 };
46
47 let prefix_constants = meta.types.meta.types.modules.values().filter_map(|module| {
48 let pfx = module.prefix()?;
49 let const_name = module.make_prefix_const()?;
50 let const_name = const_name.path.ident();
51 let prefix_literal = Literal::byte_string(pfx.as_str().as_bytes());
52
53 Some(quote! {
54 pub const #const_name: #prefix = #prefix::new_const(#prefix_literal);
55 })
56 });
57
58 module.prepend(quote! { #( #prefix_constants )* });
59 }
60}