Add polymorphic enum loop type gen.
This commit is contained in:
parent
39e9c2ddd5
commit
5a3403cc28
@ -1,6 +1,7 @@
|
||||
mod enum_type;
|
||||
mod leaf_enum_type;
|
||||
mod leaf_struct_type;
|
||||
mod polymorphic_enum_loop_type;
|
||||
mod polymorphic_type_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::struct_type::make_struct_type;
|
||||
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> {
|
||||
match build_spec {
|
||||
@ -27,7 +29,9 @@ pub fn make_type(build_spec: &BuildSpec) -> Option<TokenStream> {
|
||||
BuildSpec::PolymorphicType(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,
|
||||
}
|
||||
}
|
||||
|
||||
96
ast-generator/src/type_gen/polymorphic_enum_loop_type.rs
Normal file
96
ast-generator/src/type_gen/polymorphic_enum_loop_type.rs
Normal 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)*
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user