Add polymorphic enum loop type gen.

This commit is contained in:
Jesse Brault 2025-09-24 20:29:17 -05:00
parent 39e9c2ddd5
commit 5a3403cc28
2 changed files with 101 additions and 1 deletions

View File

@ -1,6 +1,7 @@
mod enum_type; mod enum_type;
mod leaf_enum_type; mod leaf_enum_type;
mod leaf_struct_type; mod leaf_struct_type;
mod polymorphic_enum_loop_type;
mod polymorphic_type_type; mod polymorphic_type_type;
mod struct_type; mod struct_type;
@ -11,6 +12,7 @@ use crate::type_gen::leaf_struct_type::make_leaf_struct_type;
use crate::type_gen::polymorphic_type_type::make_polymorphic_type_type; use crate::type_gen::polymorphic_type_type::make_polymorphic_type_type;
use crate::type_gen::struct_type::make_struct_type; use crate::type_gen::struct_type::make_struct_type;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use crate::type_gen::polymorphic_enum_loop_type::make_polymorphic_enum_loop_type;
pub fn make_type(build_spec: &BuildSpec) -> Option<TokenStream> { pub fn make_type(build_spec: &BuildSpec) -> Option<TokenStream> {
match build_spec { match build_spec {
@ -27,7 +29,9 @@ pub fn make_type(build_spec: &BuildSpec) -> Option<TokenStream> {
BuildSpec::PolymorphicType(polymorphic_build_spec) => { BuildSpec::PolymorphicType(polymorphic_build_spec) => {
Some(make_polymorphic_type_type(polymorphic_build_spec)) Some(make_polymorphic_type_type(polymorphic_build_spec))
} }
BuildSpec::PolymorphicEnumLoop(_) => None, BuildSpec::PolymorphicEnumLoop(polymorphic_enum_loop_spec) => {
Some(make_polymorphic_enum_loop_type(polymorphic_enum_loop_spec))
},
BuildSpec::PolymorphicPassThrough(_) => None, BuildSpec::PolymorphicPassThrough(_) => None,
} }
} }

View File

@ -0,0 +1,96 @@
use crate::spec::polymorphic_enum_loop_spec::{PolymorphicEnumLoopBuildSpec, PolymorphicEnumLoopRule, PolymorphicEnumLoopRuleBuildChild};
use proc_macro2::TokenStream;
use quote::{format_ident, quote};
pub fn make_polymorphic_enum_loop_type(spec: &PolymorphicEnumLoopBuildSpec) -> TokenStream {
let type_ident = format_ident!("{}", spec.name());
let build = spec.rules()
.find(|rule| {
match rule {
PolymorphicEnumLoopRule::Build(_) => true,
_ => false
}
})
.map(|rule| {
match rule {
PolymorphicEnumLoopRule::Build(build) => build,
_ => unreachable!()
}
})
.unwrap();
let annotated_members = build.children()
.map(|child| {
match child {
PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => {
let child_ident = format_ident!("{}", use_current.name());
let child_type_ident = format_ident!("{}", use_current.kind());
quote! {
#child_ident: Box<#child_type_ident>
}
}
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => {
let child_ident = format_ident!("{}", on_each.name());
let child_type_ident = format_ident!("{}", on_each.rule());
quote! {
#child_ident: Box<#child_type_ident>
}
}
}
})
.collect::<Vec<_>>();
let member_names = build.children()
.map(|child| {
match child {
PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => {
format_ident!("{}", use_current.name())
}
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => {
format_ident!("{}", on_each.name())
}
}
})
.collect::<Vec<_>>();
let accessors = build.children()
.map(|child| {
let (child_ident, child_type_ident) = match child {
PolymorphicEnumLoopRuleBuildChild::UseCurrent(use_current) => {
(format_ident!("{}", use_current.name()), format_ident!("{}", use_current.kind()))
}
PolymorphicEnumLoopRuleBuildChild::OnEach(on_each) => {
(format_ident!("{}", on_each.name()), format_ident!("{}", on_each.rule()))
}
};
let child_mut_ident = format_ident!("{}_mut", child_ident);
quote! {
pub fn #child_ident(&self) -> &#child_type_ident {
self.#child_ident.as_ref()
}
pub fn #child_mut_ident(&mut self) -> &mut #child_type_ident {
self.#child_ident.as_mut()
}
}
})
.collect::<Vec<_>>();
quote! {
pub struct #type_ident {
#(#annotated_members),*
}
impl #type_ident {
pub fn new(#(#annotated_members),*) -> Self {
Self {
#(#member_names),*
}
}
#(#accessors)*
}
}
}