Skeleton code for leaf_enum specs.

This commit is contained in:
Jesse Brault 2025-09-14 09:11:30 -05:00
parent 152f5a6150
commit 0704e7d504
4 changed files with 45 additions and 24 deletions

View File

@ -46,7 +46,12 @@ fn get_vec_child(name: &str, rule: &str, build: &Yaml) -> ChildSpec {
)) ))
} }
fn get_single_child_to_build(name: &str, rule: &str, optional: bool, build: &Yaml) -> SingleChildToBuild { fn get_single_child_to_build(
name: &str,
rule: &str,
optional: bool,
build: &Yaml,
) -> SingleChildToBuild {
if build.is_hash() { if build.is_hash() {
match build["type"].as_str() { match build["type"].as_str() {
Some(r#type) => { Some(r#type) => {
@ -63,15 +68,14 @@ fn get_single_child_to_build(name: &str, rule: &str, optional: bool, build: &Yam
} else { } else {
todo!("currently on boolean types with on: rule_present are supported") todo!("currently on boolean types with on: rule_present are supported")
} }
}, }
None => { None => {
let or_else = build["or_else"] let or_else = build["or_else"]
.as_str() .as_str()
.map(|s| s.to_string()) .map(|s| s.to_string())
.or_else(|| { .or_else(|| {
let or_else_default = build["or_else_default"] let or_else_default =
.as_bool() build["or_else_default"].as_bool().unwrap_or_else(|| false);
.unwrap_or_else(|| false);
if or_else_default { if or_else_default {
Some(String::from("default")) Some(String::from("default"))
} else { } else {
@ -79,16 +83,18 @@ fn get_single_child_to_build(name: &str, rule: &str, optional: bool, build: &Yam
} }
}); });
SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule( SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(
rule, rule, or_else, optional,
or_else,
optional,
)) ))
} }
} }
} else { } else {
match build.as_str() { match build.as_str() {
Some(s) => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(s, None, optional)), Some(s) => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(
None => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(rule, None, optional)), s, None, optional,
)),
None => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(
rule, None, optional,
)),
} }
} }
} }
@ -129,9 +135,7 @@ fn get_child_specs(children: &Yaml) -> Vec<ChildSpec> {
if get_vec(&props["vec"]) { if get_vec(&props["vec"]) {
get_vec_child(name, &rule, build) get_vec_child(name, &rule, build)
} else { } else {
let optional = props["optional"] let optional = props["optional"].as_bool().unwrap_or_else(|| false);
.as_bool()
.unwrap_or_else(|| false);
get_single_child(name, &rule, optional, build) get_single_child(name, &rule, optional, build)
} }
@ -142,7 +146,7 @@ fn get_child_specs(children: &Yaml) -> Vec<ChildSpec> {
.collect() .collect()
} }
fn get_enum_rule_specs(rule_specs: &Yaml) -> Vec<EnumRule> { fn get_enum_rules(rule_specs: &Yaml) -> Vec<EnumRule> {
rule_specs rule_specs
.as_vec() .as_vec()
.unwrap() .unwrap()
@ -165,24 +169,36 @@ fn get_enum_rule_specs(rule_specs: &Yaml) -> Vec<EnumRule> {
.collect() .collect()
} }
fn yaml_is_string(yaml: &Yaml, test: &str) -> bool {
match yaml.as_str() {
Some(s) => s == test,
None => false,
}
}
fn deserialize_build_spec(build_spec_name: &Yaml, build_spec: &Yaml) -> BuildSpec { fn deserialize_build_spec(build_spec_name: &Yaml, build_spec: &Yaml) -> BuildSpec {
let build_spec_name_pascal = build_spec_name.as_str().unwrap(); let build_spec_name_pascal = build_spec_name.as_str().unwrap();
let node_type = &build_spec["type"];
let children = &build_spec["children"]; let children = &build_spec["children"];
let rules = &build_spec["rules"];
if children.is_array() { if yaml_is_string(node_type, "struct") || children.is_array() {
let child_specs = get_child_specs(children); let child_specs = get_child_specs(children);
BuildSpec::Struct(StructBuildSpec::from_name( BuildSpec::Struct(StructBuildSpec::from_name(
build_spec_name_pascal, build_spec_name_pascal,
child_specs, child_specs,
)) ))
} else { } else if yaml_is_string(node_type, "leaf_enum") && rules.is_array() {
let rule_specs = &build_spec["rules"]; todo!(
if rule_specs.is_array() { "Not yet ready for leaf_enum node: {}",
let enum_rules = get_enum_rule_specs(rule_specs); build_spec_name_pascal
)
} else if rules.is_array() {
// enum node
let enum_rules = get_enum_rules(rules);
BuildSpec::Enum(EnumBuildSpec::from_name(build_spec_name_pascal, enum_rules)) BuildSpec::Enum(EnumBuildSpec::from_name(build_spec_name_pascal, enum_rules))
} else { } else {
panic!("either children or rules must be present on the build spec"); panic!("Expected a node spec for either a struct, enum, or leaf_enum node type.");
}
} }
} }

View File

@ -16,6 +16,7 @@ fn debug_built_spec(build_spec: &BuildSpec, token_stream: &TokenStream) {
BuildSpec::Enum(enum_build_spec) => { BuildSpec::Enum(enum_build_spec) => {
println!("Spec name: {}", enum_build_spec.name()); println!("Spec name: {}", enum_build_spec.name());
} }
BuildSpec::LeafEnum() => todo!(),
BuildSpec::Struct(struct_build_spec) => { BuildSpec::Struct(struct_build_spec) => {
println!("Spec name: {}", struct_build_spec.name()); println!("Spec name: {}", struct_build_spec.name());
} }
@ -40,6 +41,7 @@ fn generate_build_file(build_specs: &[BuildSpec]) -> AstGeneratedFile {
.map(|build_spec| { .map(|build_spec| {
match build_spec { match build_spec {
BuildSpec::Enum(enum_build_spec) => { quote! {} } BuildSpec::Enum(enum_build_spec) => { quote! {} }
BuildSpec::LeafEnum() => { quote! {} }
BuildSpec::Struct(struct_build_spec) => { BuildSpec::Struct(struct_build_spec) => {
let struct_build_fn_stream = make_struct_build_fn(struct_build_spec); let struct_build_fn_stream = make_struct_build_fn(struct_build_spec);
debug_built_spec(build_spec, &struct_build_fn_stream); debug_built_spec(build_spec, &struct_build_fn_stream);
@ -74,6 +76,7 @@ pub fn test_dump() -> String {
for build_spec in &build_specs { for build_spec in &build_specs {
match build_spec { match build_spec {
BuildSpec::Enum(_) => {} BuildSpec::Enum(_) => {}
BuildSpec::LeafEnum() => {}
BuildSpec::Struct(struct_spec) => { BuildSpec::Struct(struct_spec) => {
let struct_build_fn_stream = make_struct_build_fn(struct_spec); let struct_build_fn_stream = make_struct_build_fn(struct_spec);
debug_built_spec(build_spec, &struct_build_fn_stream); debug_built_spec(build_spec, &struct_build_fn_stream);

View File

@ -3,6 +3,7 @@ use convert_case::{Case, Casing};
pub enum BuildSpec { pub enum BuildSpec {
Enum(EnumBuildSpec), Enum(EnumBuildSpec),
LeafEnum(),
Struct(StructBuildSpec), Struct(StructBuildSpec),
} }

View File

@ -163,6 +163,7 @@ fn make_struct_type(build_spec: &StructBuildSpec) -> TokenStream {
pub fn make_type(build_spec: &BuildSpec) -> TokenStream { pub fn make_type(build_spec: &BuildSpec) -> TokenStream {
match build_spec { match build_spec {
BuildSpec::Enum(enum_build_spec) => make_enum_type(enum_build_spec), BuildSpec::Enum(enum_build_spec) => make_enum_type(enum_build_spec),
BuildSpec::LeafEnum() => todo!(),
BuildSpec::Struct(struct_build_spec) => make_struct_type(struct_build_spec), BuildSpec::Struct(struct_build_spec) => make_struct_type(struct_build_spec),
} }
} }