Handle deserialization of leaf_enum nodes.
This commit is contained in:
parent
0704e7d504
commit
968b950436
@ -1,18 +1,10 @@
|
||||
use crate::build_fn_gen::make_build_fn_name;
|
||||
use crate::spec::{
|
||||
BuildBooleanOn, BuildSpec, ChildSpec, EnumBuildSpec, EnumRule, SingleBooleanChildToBuild,
|
||||
SingleChild, SingleChildToBuild, SingleTypeChildToBuild, SkipChild, StructBuildSpec, VecChild,
|
||||
VecChildToBuild, VecTypeChildToBuild,
|
||||
};
|
||||
use crate::spec::{BuildBooleanOn, BuildSpec, ChildSpec, EnumBuildSpec, EnumRule, LeafEnumBuildSpec, LeafEnumRule, LeafEnumRuleBuild, SingleBooleanChildToBuild, SingleChild, SingleChildToBuild, SingleTypeChildToBuild, SkipChild, StructBuildSpec, VecChild, VecChildToBuild, VecTypeChildToBuild};
|
||||
use convert_case::{Case, Casing};
|
||||
use yaml_rust2::{Yaml, YamlLoader};
|
||||
|
||||
fn get_skip(skip: &Yaml) -> bool {
|
||||
skip.as_bool().unwrap_or_else(|| false)
|
||||
}
|
||||
|
||||
fn get_vec(vec: &Yaml) -> bool {
|
||||
vec.as_bool().unwrap_or_else(|| false)
|
||||
fn get_as_bool(yaml: &Yaml) -> bool {
|
||||
yaml.as_bool().unwrap_or_else(|| false)
|
||||
}
|
||||
|
||||
fn get_vec_child_to_build(build: &Yaml, name: &str, rule: &str) -> VecChildToBuild {
|
||||
@ -126,13 +118,13 @@ fn get_child_specs(children: &Yaml) -> Vec<ChildSpec> {
|
||||
.map(|s| s.to_string())
|
||||
.unwrap_or(name.to_case(Case::Pascal));
|
||||
|
||||
if get_skip(&props["skip"]) {
|
||||
if get_as_bool(&props["skip"]) {
|
||||
return ChildSpec::SkipChild(SkipChild::new(name, &rule));
|
||||
}
|
||||
|
||||
let build = &props["build"];
|
||||
|
||||
if get_vec(&props["vec"]) {
|
||||
if get_as_bool(&props["vec"]) {
|
||||
get_vec_child(name, &rule, build)
|
||||
} else {
|
||||
let optional = props["optional"].as_bool().unwrap_or_else(|| false);
|
||||
@ -146,6 +138,45 @@ fn get_child_specs(children: &Yaml) -> Vec<ChildSpec> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn unwrap_single_member_hash(hash: &Yaml) -> (String, &Yaml) {
|
||||
let as_hash = hash.as_hash().unwrap();
|
||||
if as_hash.is_empty() {
|
||||
panic!("empty hash");
|
||||
} else if as_hash.len() > 1 {
|
||||
panic!("hash contains more than one key");
|
||||
}
|
||||
let (member_key, member_value) = as_hash.iter().collect::<Vec<(&Yaml, &Yaml)>>()[0];
|
||||
let key_as_string = member_key.as_str().unwrap().to_string();
|
||||
(key_as_string, member_value)
|
||||
}
|
||||
|
||||
fn get_leaf_enum_rules(rules: &Yaml) -> Vec<LeafEnumRule> {
|
||||
rules
|
||||
.as_vec()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|rule| {
|
||||
if rule.is_hash() {
|
||||
let (rule_as_string, rule_hash) = unwrap_single_member_hash(rule);
|
||||
if get_as_bool(&rule_hash["child"]) {
|
||||
let build = LeafEnumRuleBuild::Child {
|
||||
with: make_build_fn_name(&rule_as_string)
|
||||
};
|
||||
LeafEnumRule::new(&rule_as_string, build)
|
||||
} else {
|
||||
panic!("if a leaf_enum rule is a hash, its child prop must be present and true");
|
||||
}
|
||||
} else {
|
||||
let rule_as_str = rule.as_str().unwrap();
|
||||
let build = LeafEnumRuleBuild::EnumRule {
|
||||
rule: rule_as_str.to_string(),
|
||||
};
|
||||
LeafEnumRule::new(rule_as_str, build)
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_enum_rules(rule_specs: &Yaml) -> Vec<EnumRule> {
|
||||
rule_specs
|
||||
.as_vec()
|
||||
@ -189,10 +220,8 @@ fn deserialize_build_spec(build_spec_name: &Yaml, build_spec: &Yaml) -> BuildSpe
|
||||
child_specs,
|
||||
))
|
||||
} else if yaml_is_string(node_type, "leaf_enum") && rules.is_array() {
|
||||
todo!(
|
||||
"Not yet ready for leaf_enum node: {}",
|
||||
build_spec_name_pascal
|
||||
)
|
||||
let leaf_enum_rules = get_leaf_enum_rules(rules);
|
||||
BuildSpec::LeafEnum(LeafEnumBuildSpec::from_name(build_spec_name_pascal, leaf_enum_rules))
|
||||
} else if rules.is_array() {
|
||||
// enum node
|
||||
let enum_rules = get_enum_rules(rules);
|
||||
|
||||
@ -16,7 +16,9 @@ fn debug_built_spec(build_spec: &BuildSpec, token_stream: &TokenStream) {
|
||||
BuildSpec::Enum(enum_build_spec) => {
|
||||
println!("Spec name: {}", enum_build_spec.name());
|
||||
}
|
||||
BuildSpec::LeafEnum() => todo!(),
|
||||
BuildSpec::LeafEnum(leaf_enum_build_spec) => {
|
||||
println!("Spec name: {}", leaf_enum_build_spec.name());
|
||||
},
|
||||
BuildSpec::Struct(struct_build_spec) => {
|
||||
println!("Spec name: {}", struct_build_spec.name());
|
||||
}
|
||||
@ -41,7 +43,7 @@ fn generate_build_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
|
||||
.map(|build_spec| {
|
||||
match build_spec {
|
||||
BuildSpec::Enum(enum_build_spec) => { quote! {} }
|
||||
BuildSpec::LeafEnum() => { quote! {} }
|
||||
BuildSpec::LeafEnum(leaf_enum_build_spec) => { quote! {} }
|
||||
BuildSpec::Struct(struct_build_spec) => {
|
||||
let struct_build_fn_stream = make_struct_build_fn(struct_build_spec);
|
||||
debug_built_spec(build_spec, &struct_build_fn_stream);
|
||||
@ -76,7 +78,7 @@ pub fn test_dump() -> String {
|
||||
for build_spec in &build_specs {
|
||||
match build_spec {
|
||||
BuildSpec::Enum(_) => {}
|
||||
BuildSpec::LeafEnum() => {}
|
||||
BuildSpec::LeafEnum(_) => {}
|
||||
BuildSpec::Struct(struct_spec) => {
|
||||
let struct_build_fn_stream = make_struct_build_fn(struct_spec);
|
||||
debug_built_spec(build_spec, &struct_build_fn_stream);
|
||||
|
||||
@ -3,7 +3,7 @@ use convert_case::{Case, Casing};
|
||||
|
||||
pub enum BuildSpec {
|
||||
Enum(EnumBuildSpec),
|
||||
LeafEnum(),
|
||||
LeafEnum(LeafEnumBuildSpec),
|
||||
Struct(StructBuildSpec),
|
||||
}
|
||||
|
||||
@ -77,6 +77,65 @@ impl EnumRule {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LeafEnumBuildSpec {
|
||||
name: String,
|
||||
build: String,
|
||||
rules: Vec<LeafEnumRule>,
|
||||
}
|
||||
|
||||
impl LeafEnumBuildSpec {
|
||||
pub fn from_name(name: &str, rules: Vec<LeafEnumRule>) -> Self {
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
build: name.to_string(),
|
||||
rules
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
pub fn build(&self) -> &str {
|
||||
&self.build
|
||||
}
|
||||
|
||||
pub fn rules(&self) -> &[LeafEnumRule] {
|
||||
&self.rules
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LeafEnumRule {
|
||||
rule: String,
|
||||
build: LeafEnumRuleBuild
|
||||
}
|
||||
|
||||
impl LeafEnumRule {
|
||||
pub fn new(rule: &str, build: LeafEnumRuleBuild) -> Self {
|
||||
Self {
|
||||
rule: rule.to_string(),
|
||||
build
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rule(&self) -> &str {
|
||||
&self.rule
|
||||
}
|
||||
|
||||
pub fn build(&self) -> &LeafEnumRuleBuild {
|
||||
&self.build
|
||||
}
|
||||
}
|
||||
|
||||
pub enum LeafEnumRuleBuild {
|
||||
EnumRule {
|
||||
rule: String,
|
||||
},
|
||||
Child {
|
||||
with: String
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StructBuildSpec {
|
||||
name: String,
|
||||
build: String,
|
||||
|
||||
@ -163,7 +163,7 @@ fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream {
|
||||
pub fn make_type(build_spec: &BuildSpec) -> TokenStream {
|
||||
match build_spec {
|
||||
BuildSpec::Enum(enum_build_spec) => make_enum_type(enum_build_spec),
|
||||
BuildSpec::LeafEnum() => todo!(),
|
||||
BuildSpec::LeafEnum(leaf_enum_build_spec) => todo!(),
|
||||
BuildSpec::Struct(struct_build_spec) => make_struct_type(struct_build_spec),
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user