Refactor build fn for struct nodes.
This commit is contained in:
parent
63643d86ba
commit
4d2e76338a
@ -1,8 +1,8 @@
|
||||
pub(crate) mod enum_build_fn;
|
||||
pub(crate) mod leaf_enum_build_fn;
|
||||
pub(crate) mod leaf_struct_build_fn;
|
||||
pub(crate) mod polymorphic_build_build_fn;
|
||||
pub(crate) mod polymorphic_build_fn;
|
||||
pub(crate) mod polymorphic_enum_build_fn;
|
||||
pub(crate) mod production_build_fn;
|
||||
pub(crate) mod struct_build_fn;
|
||||
pub mod enum_build_fn;
|
||||
pub mod leaf_enum_build_fn;
|
||||
pub mod leaf_struct_build_fn;
|
||||
pub mod polymorphic_build_build_fn;
|
||||
pub mod polymorphic_build_fn;
|
||||
pub mod polymorphic_enum_build_fn;
|
||||
pub mod production_build_fn;
|
||||
pub mod struct_build_fn;
|
||||
|
||||
@ -1,32 +1,28 @@
|
||||
use crate::spec::{
|
||||
BooleanChildToBuild, MemberChildToBuild, NodeChildToBuild, StructBuildSpec, StructChildSpec,
|
||||
VecChild, VecChildToBuild,
|
||||
use crate::deserialize::util::{make_build_fn_name, make_build_pair};
|
||||
use crate::spec::struct_spec::{
|
||||
MemberChildBuild, NodeMemberBuild, StructChild, StructSpec, VecChild, VecChildBuild,
|
||||
};
|
||||
use crate::util::{make_build_fn_name, make_build_pair};
|
||||
use convert_case::{Case, Casing};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
|
||||
fn make_var_name(s: &str) -> String {
|
||||
s.to_case(Case::Snake)
|
||||
}
|
||||
|
||||
fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream {
|
||||
let child_ident = format_ident!("{}", vec_child.name());
|
||||
match vec_child.build() {
|
||||
VecChildToBuild::Node(node_child) => {
|
||||
let child_type_ident = format_ident!("{}", node_child.build());
|
||||
VecChildBuild::String(_) => {
|
||||
quote! {
|
||||
let mut #child_ident: Vec<String> = vec![]
|
||||
}
|
||||
}
|
||||
VecChildBuild::Node(node_build) => {
|
||||
let child_type_ident = format_ident!("{}", node_build.kind());
|
||||
quote! {
|
||||
let mut #child_ident: Vec<Box<#child_type_ident>> = vec![]
|
||||
}
|
||||
}
|
||||
VecChildToBuild::String => quote! {
|
||||
let mut #child_ident: Vec<String> = vec![]
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn make_node_child_holder(name: &str, node_child: &NodeChildToBuild) -> TokenStream {
|
||||
fn make_node_child_holder(name: &str, node_child: &NodeMemberBuild) -> TokenStream {
|
||||
let child_ident = format_ident!("{}", name);
|
||||
let child_type_ident = format_ident!("{}", node_child.kind());
|
||||
quote! {
|
||||
@ -34,24 +30,22 @@ fn make_node_child_holder(name: &str, node_child: &NodeChildToBuild) -> TokenStr
|
||||
}
|
||||
}
|
||||
|
||||
fn make_boolean_child_holder(boolean_child: &BooleanChildToBuild) -> TokenStream {
|
||||
let child_ident = format_ident!("{}", boolean_child.name());
|
||||
fn make_boolean_child_holder(name: &str) -> TokenStream {
|
||||
let child_ident = format_ident!("{}", name);
|
||||
quote! {
|
||||
let mut #child_ident: bool = false
|
||||
}
|
||||
}
|
||||
|
||||
fn make_child_holder(child_spec: &StructChildSpec) -> Option<TokenStream> {
|
||||
fn make_child_holder(child_spec: &StructChild) -> Option<TokenStream> {
|
||||
match child_spec {
|
||||
StructChildSpec::SkipChild(_) => None,
|
||||
StructChildSpec::VecChild(vec_child) => Some(make_vec_child_holder(vec_child)),
|
||||
StructChildSpec::MemberChild(member_child) => match member_child.build() {
|
||||
MemberChildToBuild::Node(node_child) => {
|
||||
StructChild::SkipChild(_) => None,
|
||||
StructChild::VecChild(vec_child) => Some(make_vec_child_holder(vec_child)),
|
||||
StructChild::MemberChild(member_child) => match member_child.build() {
|
||||
MemberChildBuild::Node(node_child) => {
|
||||
Some(make_node_child_holder(member_child.name(), node_child))
|
||||
}
|
||||
MemberChildToBuild::Boolean(boolean_child) => {
|
||||
Some(make_boolean_child_holder(boolean_child))
|
||||
}
|
||||
MemberChildBuild::Boolean(_) => Some(make_boolean_child_holder(member_child.name())),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -59,56 +53,56 @@ fn make_child_holder(child_spec: &StructChildSpec) -> Option<TokenStream> {
|
||||
fn make_vec_child_match_action(vec_child: &VecChild) -> TokenStream {
|
||||
let child_name_ident = format_ident!("{}", vec_child.name());
|
||||
match vec_child.build() {
|
||||
VecChildToBuild::Node(vec_node_child) => {
|
||||
let build_fn_ident = format_ident!("{}", make_build_fn_name(vec_node_child.build()));
|
||||
quote! {
|
||||
#child_name_ident.push(Box::new(#build_fn_ident(inner_pair)))
|
||||
}
|
||||
}
|
||||
VecChildToBuild::String => {
|
||||
let build_fn_ident = format_ident!("{}", make_build_fn_name(vec_child.rule()));
|
||||
VecChildBuild::String(string_build) => {
|
||||
let build_fn_ident = format_ident!("{}", string_build.with());
|
||||
quote! {
|
||||
#child_name_ident.push(#build_fn_ident(inner_pair))
|
||||
}
|
||||
}
|
||||
VecChildBuild::Node(node_build) => {
|
||||
let build_fn_ident = format_ident!("{}", node_build.with());
|
||||
quote! {
|
||||
#child_name_ident.push(Box::new(#build_fn_ident(inner_pair)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_node_member_child_match_action(name: &str, node_child: &NodeChildToBuild) -> TokenStream {
|
||||
fn make_node_member_child_match_action(name: &str, node_child: &NodeMemberBuild) -> TokenStream {
|
||||
let child_name_ident = format_ident!("{}", name);
|
||||
let build_fn_ident = format_ident!("{}", make_build_fn_name(node_child.kind()));
|
||||
let build_fn_ident = format_ident!("{}", node_child.with());
|
||||
quote! {
|
||||
#child_name_ident = Some(Box::new(#build_fn_ident(inner_pair)))
|
||||
}
|
||||
}
|
||||
|
||||
fn make_boolean_member_child_match_action(boolean_child: &BooleanChildToBuild) -> TokenStream {
|
||||
let child_name_ident = format_ident!("{}", make_var_name(boolean_child.name()));
|
||||
fn make_boolean_member_child_match_action(name: &str) -> TokenStream {
|
||||
let child_name_ident = format_ident!("{}", name);
|
||||
quote! {
|
||||
#child_name_ident = true
|
||||
}
|
||||
}
|
||||
|
||||
fn make_match_action(child_spec: &StructChildSpec) -> TokenStream {
|
||||
fn make_match_action(child_spec: &StructChild) -> TokenStream {
|
||||
match child_spec {
|
||||
StructChildSpec::SkipChild(_) => quote! {},
|
||||
StructChildSpec::VecChild(vec_child) => make_vec_child_match_action(vec_child),
|
||||
StructChildSpec::MemberChild(member_child) => match member_child.build() {
|
||||
MemberChildToBuild::Node(node_child) => {
|
||||
StructChild::SkipChild(_) => quote! {},
|
||||
StructChild::VecChild(vec_child) => make_vec_child_match_action(vec_child),
|
||||
StructChild::MemberChild(member_child) => match member_child.build() {
|
||||
MemberChildBuild::Node(node_child) => {
|
||||
make_node_member_child_match_action(member_child.name(), node_child)
|
||||
}
|
||||
MemberChildToBuild::Boolean(boolean_child) => {
|
||||
make_boolean_member_child_match_action(boolean_child)
|
||||
MemberChildBuild::Boolean(_) => {
|
||||
make_boolean_member_child_match_action(member_child.name())
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn make_rule_matcher(child_spec: &StructChildSpec) -> TokenStream {
|
||||
fn make_rule_matcher(child_spec: &StructChild) -> TokenStream {
|
||||
let rule_ident = match child_spec {
|
||||
StructChildSpec::SkipChild(skip_child) => format_ident!("{}", skip_child.rule()),
|
||||
StructChildSpec::VecChild(vec_child) => format_ident!("{}", vec_child.rule()),
|
||||
StructChildSpec::MemberChild(single_child) => format_ident!("{}", single_child.rule()),
|
||||
StructChild::SkipChild(skip_child) => format_ident!("{}", skip_child.rule()),
|
||||
StructChild::VecChild(vec_child) => format_ident!("{}", vec_child.rule()),
|
||||
StructChild::MemberChild(single_child) => format_ident!("{}", single_child.rule()),
|
||||
};
|
||||
let action = make_match_action(child_spec);
|
||||
|
||||
@ -124,9 +118,13 @@ fn make_vec_child_arg(vec_child: &VecChild) -> TokenStream {
|
||||
quote! { #child_ident }
|
||||
}
|
||||
|
||||
fn make_node_member_child_arg(name: &str, node_child: &NodeChildToBuild) -> TokenStream {
|
||||
fn make_node_member_child_arg(
|
||||
name: &str,
|
||||
optional: bool,
|
||||
node_child: &NodeMemberBuild,
|
||||
) -> TokenStream {
|
||||
let child_ident = format_ident!("{}", name);
|
||||
if node_child.optional() {
|
||||
if optional {
|
||||
quote! { #child_ident }
|
||||
} else if let Some(or_else) = node_child.or_else() {
|
||||
let child_type_ident = format_ident!("{}", node_child.kind());
|
||||
@ -139,28 +137,29 @@ fn make_node_member_child_arg(name: &str, node_child: &NodeChildToBuild) -> Toke
|
||||
}
|
||||
}
|
||||
|
||||
fn make_boolean_member_child_arg(boolean_child: &BooleanChildToBuild) -> TokenStream {
|
||||
let child_ident = format_ident!("{}", boolean_child.name());
|
||||
fn make_boolean_member_child_arg(name: &str) -> TokenStream {
|
||||
let child_ident = format_ident!("{}", name);
|
||||
quote! { #child_ident }
|
||||
}
|
||||
|
||||
fn make_child_arg(child_spec: &StructChildSpec) -> Option<TokenStream> {
|
||||
fn make_child_arg(child_spec: &StructChild) -> Option<TokenStream> {
|
||||
match child_spec {
|
||||
StructChildSpec::SkipChild(_) => None,
|
||||
StructChildSpec::VecChild(vec_child) => Some(make_vec_child_arg(vec_child)),
|
||||
StructChildSpec::MemberChild(member_child) => match member_child.build() {
|
||||
MemberChildToBuild::Node(single_type_child) => Some(make_node_member_child_arg(
|
||||
StructChild::SkipChild(_) => None,
|
||||
StructChild::VecChild(vec_child) => Some(make_vec_child_arg(vec_child)),
|
||||
StructChild::MemberChild(member_child) => match member_child.build() {
|
||||
MemberChildBuild::Node(node_member_build) => Some(make_node_member_child_arg(
|
||||
member_child.name(),
|
||||
single_type_child,
|
||||
member_child.optional(),
|
||||
node_member_build,
|
||||
)),
|
||||
MemberChildToBuild::Boolean(boolean_child) => {
|
||||
Some(make_boolean_member_child_arg(boolean_child))
|
||||
MemberChildBuild::Boolean(_) => {
|
||||
Some(make_boolean_member_child_arg(member_child.name()))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn make_return_value_stream(build_spec: &StructBuildSpec) -> TokenStream {
|
||||
fn make_return_value_stream(build_spec: &StructSpec) -> TokenStream {
|
||||
let type_ident = format_ident!("{}", build_spec.build());
|
||||
let child_args = build_spec
|
||||
.children()
|
||||
@ -176,7 +175,7 @@ fn make_return_value_stream(build_spec: &StructBuildSpec) -> TokenStream {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_struct_build_fn(build_spec: &StructBuildSpec) -> TokenStream {
|
||||
pub fn make_struct_build_fn(build_spec: &StructSpec) -> TokenStream {
|
||||
let build_fn_ident = format_ident!("{}", make_build_fn_name(build_spec.build()));
|
||||
let pair_ident = format_ident!("{}", make_build_pair(build_spec.build()));
|
||||
let return_type_ident = format_ident!("{}", build_spec.build());
|
||||
|
||||
@ -14,7 +14,22 @@ fn deserialize_vec_child(child_name: &str, props: &Yaml) -> StructChild {
|
||||
let rule = props["rule"].as_str().unwrap();
|
||||
let kind = props["kind"].as_str()
|
||||
.unwrap_or(rule);
|
||||
StructChild::VecChild(VecChild::new(child_name, rule, kind))
|
||||
if kind == "string" {
|
||||
let build = VecChildBuild::String(VecChildStringBuild::new(
|
||||
&make_build_fn_name(rule)
|
||||
));
|
||||
StructChild::VecChild(VecChild::new(
|
||||
child_name,
|
||||
rule,
|
||||
Box::new(build),
|
||||
))
|
||||
} else {
|
||||
let build = VecChildBuild::Node(VecChildNodeBuild::new(
|
||||
rule,
|
||||
&make_build_fn_name(rule)
|
||||
));
|
||||
StructChild::VecChild(VecChild::new(child_name, rule, Box::new(build)))
|
||||
}
|
||||
}
|
||||
|
||||
fn deserialize_member_build(child_name: &str, rule: &str, props: &Yaml) -> MemberChildBuild {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user