xsd_parser/pipeline/renderer/steps/
enum_const.rs1use std::str::FromStr;
2
3use proc_macro2::TokenStream;
4use quote::quote;
5
6use crate::models::data::{EnumerationData, EnumerationDataVariant, EnumerationVariantValue};
7
8use super::super::{Context, DataTypeVariant, RenderStep, RenderStepType};
9
10#[derive(Debug, Clone, Copy)]
12pub struct EnumConstantsRenderStep;
13
14impl RenderStep for EnumConstantsRenderStep {
15 fn render_step_type(&self) -> RenderStepType {
16 RenderStepType::Types
17 }
18
19 fn render_type(&mut self, ctx: &mut Context<'_, '_>) {
20 if let DataTypeVariant::Enumeration(x) = &ctx.data.variant {
21 x.render_enum_constants(ctx);
22 }
23 }
24}
25
26impl EnumerationData<'_> {
29 fn render_enum_constants(&self, ctx: &mut Context<'_, '_>) {
30 let Some(base) = &self.simple_base_type else {
31 return;
32 };
33 let base = ctx.resolve_type_for_module(base);
34
35 let variants = self
36 .variants
37 .iter()
38 .filter_map(|var| var.render_enum_value(ctx, &base))
39 .collect::<Vec<_>>();
40 if variants.is_empty() {
41 return;
42 }
43
44 let type_ident = &self.type_ident;
45
46 let code = quote! {
47 impl #type_ident {
48 #( #variants )*
49 }
50 };
51
52 ctx.current_module().append(code);
53 }
54}
55
56impl EnumerationDataVariant<'_> {
57 fn render_enum_value(&self, ctx: &Context<'_, '_>, base: &TokenStream) -> Option<TokenStream> {
58 match &self.value {
59 EnumerationVariantValue::None => None,
60 EnumerationVariantValue::ByteLiteral(ident, renderer) => {
61 let value = renderer.render(ctx);
62 let value = value.to_string();
63 let value = value.trim_start_matches('b');
64 let value = TokenStream::from_str(value).unwrap();
65 let str_ = ctx.resolve_build_in("::core::primitive::str");
66
67 Some(quote! {
68 pub const #ident: &#str_ = #value;
69 })
70 }
71 EnumerationVariantValue::Constant(ident, renderer) => {
72 let value = renderer.render(ctx);
73
74 Some(quote! {
75 pub const #ident: &'static #base = &#value;
76 })
77 }
78 }
79 }
80}