Skip to main content

xsd_parser/pipeline/renderer/steps/
enum_const.rs

1use 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/// Implements a [`RenderStep`] that renders the actual rust types of the types defined in the schema.
11#[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
26/* EnumerationData */
27
28impl 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}