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 mod enum_build_fn;
|
||||||
pub(crate) mod leaf_enum_build_fn;
|
pub mod leaf_enum_build_fn;
|
||||||
pub(crate) mod leaf_struct_build_fn;
|
pub mod leaf_struct_build_fn;
|
||||||
pub(crate) mod polymorphic_build_build_fn;
|
pub mod polymorphic_build_build_fn;
|
||||||
pub(crate) mod polymorphic_build_fn;
|
pub mod polymorphic_build_fn;
|
||||||
pub(crate) mod polymorphic_enum_build_fn;
|
pub mod polymorphic_enum_build_fn;
|
||||||
pub(crate) mod production_build_fn;
|
pub mod production_build_fn;
|
||||||
pub(crate) mod struct_build_fn;
|
pub mod struct_build_fn;
|
||||||
|
|||||||
@ -1,32 +1,28 @@
|
|||||||
use crate::spec::{
|
use crate::deserialize::util::{make_build_fn_name, make_build_pair};
|
||||||
BooleanChildToBuild, MemberChildToBuild, NodeChildToBuild, StructBuildSpec, StructChildSpec,
|
use crate::spec::struct_spec::{
|
||||||
VecChild, VecChildToBuild,
|
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 proc_macro2::TokenStream;
|
||||||
use quote::{format_ident, quote};
|
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 {
|
fn make_vec_child_holder(vec_child: &VecChild) -> TokenStream {
|
||||||
let child_ident = format_ident!("{}", vec_child.name());
|
let child_ident = format_ident!("{}", vec_child.name());
|
||||||
match vec_child.build() {
|
match vec_child.build() {
|
||||||
VecChildToBuild::Node(node_child) => {
|
VecChildBuild::String(_) => {
|
||||||
let child_type_ident = format_ident!("{}", node_child.build());
|
|
||||||
quote! {
|
quote! {
|
||||||
let mut #child_ident: Vec<Box<#child_type_ident >> = vec![]
|
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_ident = format_ident!("{}", name);
|
||||||
let child_type_ident = format_ident!("{}", node_child.kind());
|
let child_type_ident = format_ident!("{}", node_child.kind());
|
||||||
quote! {
|
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 {
|
fn make_boolean_child_holder(name: &str) -> TokenStream {
|
||||||
let child_ident = format_ident!("{}", boolean_child.name());
|
let child_ident = format_ident!("{}", name);
|
||||||
quote! {
|
quote! {
|
||||||
let mut #child_ident: bool = false
|
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 {
|
match child_spec {
|
||||||
StructChildSpec::SkipChild(_) => None,
|
StructChild::SkipChild(_) => None,
|
||||||
StructChildSpec::VecChild(vec_child) => Some(make_vec_child_holder(vec_child)),
|
StructChild::VecChild(vec_child) => Some(make_vec_child_holder(vec_child)),
|
||||||
StructChildSpec::MemberChild(member_child) => match member_child.build() {
|
StructChild::MemberChild(member_child) => match member_child.build() {
|
||||||
MemberChildToBuild::Node(node_child) => {
|
MemberChildBuild::Node(node_child) => {
|
||||||
Some(make_node_child_holder(member_child.name(), node_child))
|
Some(make_node_child_holder(member_child.name(), node_child))
|
||||||
}
|
}
|
||||||
MemberChildToBuild::Boolean(boolean_child) => {
|
MemberChildBuild::Boolean(_) => Some(make_boolean_child_holder(member_child.name())),
|
||||||
Some(make_boolean_child_holder(boolean_child))
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,56 +53,56 @@ fn make_child_holder(child_spec: &StructChildSpec) -> Option<TokenStream> {
|
|||||||
fn make_vec_child_match_action(vec_child: &VecChild) -> TokenStream {
|
fn make_vec_child_match_action(vec_child: &VecChild) -> TokenStream {
|
||||||
let child_name_ident = format_ident!("{}", vec_child.name());
|
let child_name_ident = format_ident!("{}", vec_child.name());
|
||||||
match vec_child.build() {
|
match vec_child.build() {
|
||||||
VecChildToBuild::Node(vec_node_child) => {
|
VecChildBuild::String(string_build) => {
|
||||||
let build_fn_ident = format_ident!("{}", make_build_fn_name(vec_node_child.build()));
|
let build_fn_ident = format_ident!("{}", string_build.with());
|
||||||
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()));
|
|
||||||
quote! {
|
quote! {
|
||||||
#child_name_ident.push(#build_fn_ident(inner_pair))
|
#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 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! {
|
quote! {
|
||||||
#child_name_ident = Some(Box::new(#build_fn_ident(inner_pair)))
|
#child_name_ident = Some(Box::new(#build_fn_ident(inner_pair)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_boolean_member_child_match_action(boolean_child: &BooleanChildToBuild) -> TokenStream {
|
fn make_boolean_member_child_match_action(name: &str) -> TokenStream {
|
||||||
let child_name_ident = format_ident!("{}", make_var_name(boolean_child.name()));
|
let child_name_ident = format_ident!("{}", name);
|
||||||
quote! {
|
quote! {
|
||||||
#child_name_ident = true
|
#child_name_ident = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_match_action(child_spec: &StructChildSpec) -> TokenStream {
|
fn make_match_action(child_spec: &StructChild) -> TokenStream {
|
||||||
match child_spec {
|
match child_spec {
|
||||||
StructChildSpec::SkipChild(_) => quote! {},
|
StructChild::SkipChild(_) => quote! {},
|
||||||
StructChildSpec::VecChild(vec_child) => make_vec_child_match_action(vec_child),
|
StructChild::VecChild(vec_child) => make_vec_child_match_action(vec_child),
|
||||||
StructChildSpec::MemberChild(member_child) => match member_child.build() {
|
StructChild::MemberChild(member_child) => match member_child.build() {
|
||||||
MemberChildToBuild::Node(node_child) => {
|
MemberChildBuild::Node(node_child) => {
|
||||||
make_node_member_child_match_action(member_child.name(), node_child)
|
make_node_member_child_match_action(member_child.name(), node_child)
|
||||||
}
|
}
|
||||||
MemberChildToBuild::Boolean(boolean_child) => {
|
MemberChildBuild::Boolean(_) => {
|
||||||
make_boolean_member_child_match_action(boolean_child)
|
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 {
|
let rule_ident = match child_spec {
|
||||||
StructChildSpec::SkipChild(skip_child) => format_ident!("{}", skip_child.rule()),
|
StructChild::SkipChild(skip_child) => format_ident!("{}", skip_child.rule()),
|
||||||
StructChildSpec::VecChild(vec_child) => format_ident!("{}", vec_child.rule()),
|
StructChild::VecChild(vec_child) => format_ident!("{}", vec_child.rule()),
|
||||||
StructChildSpec::MemberChild(single_child) => format_ident!("{}", single_child.rule()),
|
StructChild::MemberChild(single_child) => format_ident!("{}", single_child.rule()),
|
||||||
};
|
};
|
||||||
let action = make_match_action(child_spec);
|
let action = make_match_action(child_spec);
|
||||||
|
|
||||||
@ -124,9 +118,13 @@ fn make_vec_child_arg(vec_child: &VecChild) -> TokenStream {
|
|||||||
quote! { #child_ident }
|
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);
|
let child_ident = format_ident!("{}", name);
|
||||||
if node_child.optional() {
|
if optional {
|
||||||
quote! { #child_ident }
|
quote! { #child_ident }
|
||||||
} else if let Some(or_else) = node_child.or_else() {
|
} else if let Some(or_else) = node_child.or_else() {
|
||||||
let child_type_ident = format_ident!("{}", node_child.kind());
|
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 {
|
fn make_boolean_member_child_arg(name: &str) -> TokenStream {
|
||||||
let child_ident = format_ident!("{}", boolean_child.name());
|
let child_ident = format_ident!("{}", name);
|
||||||
quote! { #child_ident }
|
quote! { #child_ident }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_child_arg(child_spec: &StructChildSpec) -> Option<TokenStream> {
|
fn make_child_arg(child_spec: &StructChild) -> Option<TokenStream> {
|
||||||
match child_spec {
|
match child_spec {
|
||||||
StructChildSpec::SkipChild(_) => None,
|
StructChild::SkipChild(_) => None,
|
||||||
StructChildSpec::VecChild(vec_child) => Some(make_vec_child_arg(vec_child)),
|
StructChild::VecChild(vec_child) => Some(make_vec_child_arg(vec_child)),
|
||||||
StructChildSpec::MemberChild(member_child) => match member_child.build() {
|
StructChild::MemberChild(member_child) => match member_child.build() {
|
||||||
MemberChildToBuild::Node(single_type_child) => Some(make_node_member_child_arg(
|
MemberChildBuild::Node(node_member_build) => Some(make_node_member_child_arg(
|
||||||
member_child.name(),
|
member_child.name(),
|
||||||
single_type_child,
|
member_child.optional(),
|
||||||
|
node_member_build,
|
||||||
)),
|
)),
|
||||||
MemberChildToBuild::Boolean(boolean_child) => {
|
MemberChildBuild::Boolean(_) => {
|
||||||
Some(make_boolean_member_child_arg(boolean_child))
|
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 type_ident = format_ident!("{}", build_spec.build());
|
||||||
let child_args = build_spec
|
let child_args = build_spec
|
||||||
.children()
|
.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 build_fn_ident = format_ident!("{}", make_build_fn_name(build_spec.build()));
|
||||||
let pair_ident = format_ident!("{}", make_build_pair(build_spec.build()));
|
let pair_ident = format_ident!("{}", make_build_pair(build_spec.build()));
|
||||||
let return_type_ident = format_ident!("{}", 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 rule = props["rule"].as_str().unwrap();
|
||||||
let kind = props["kind"].as_str()
|
let kind = props["kind"].as_str()
|
||||||
.unwrap_or(rule);
|
.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 {
|
fn deserialize_member_build(child_name: &str, rule: &str, props: &Yaml) -> MemberChildBuild {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user