Implement optionality for types.

This commit is contained in:
Jesse Brault 2025-09-03 17:12:19 -05:00
parent 3b07cef209
commit 9f3f3e0f0d
3 changed files with 25 additions and 15 deletions

View File

@ -46,7 +46,7 @@ fn get_vec_child(name: &str, rule: &str, build: &Yaml) -> ChildSpec {
))
}
fn get_single_child_to_build(name: &str, rule: &str, build: &Yaml) -> SingleChildToBuild {
fn get_single_child_to_build(name: &str, rule: &str, optional: bool, build: &Yaml) -> SingleChildToBuild {
if build.is_hash() {
let r#type = build["type"].as_str().unwrap();
let var_name = build["var"]
@ -64,18 +64,17 @@ fn get_single_child_to_build(name: &str, rule: &str, build: &Yaml) -> SingleChil
}
} else {
match build.as_str() {
Some(s) => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(s)),
None => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(rule)),
Some(s) => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(s, optional)),
None => SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(rule, optional)),
}
}
}
fn get_single_child(name: &str, rule: &str, build: &Yaml, optional: bool) -> ChildSpec {
fn get_single_child(name: &str, rule: &str, optional: bool, build: &Yaml) -> ChildSpec {
ChildSpec::SingleChild(SingleChild::new(
name,
rule,
get_single_child_to_build(name, rule, build),
optional
get_single_child_to_build(name, rule, optional, build),
))
}
@ -111,7 +110,7 @@ fn get_child_specs(children: &Yaml) -> Vec<ChildSpec> {
.as_bool()
.unwrap_or_else(|| false);
get_single_child(name, &rule, build, optional)
get_single_child(name, &rule, optional, build)
}
} else {
ChildSpec::SingleChild(SingleChild::from_name_snake(child_spec.as_str().unwrap()))

View File

@ -224,7 +224,6 @@ pub struct SingleChild {
name: String,
rule: String,
build: SingleChildToBuild,
optional: bool
}
impl SingleChild {
@ -234,17 +233,16 @@ impl SingleChild {
rule: name.to_case(Case::Pascal),
build: SingleChildToBuild::Type(SingleTypeChildToBuild::from_build_or_rule(
&name.to_case(Case::Pascal),
false,
)),
optional: false,
}
}
pub fn new(name: &str, rule: &str, build: SingleChildToBuild, optional: bool) -> Self {
pub fn new(name: &str, rule: &str, build: SingleChildToBuild) -> Self {
Self {
name: name.to_string(),
rule: rule.to_string(),
build,
optional
}
}
@ -275,14 +273,16 @@ pub struct SingleTypeChildToBuild {
build: String,
var_name: String,
with: String,
optional: bool,
}
impl SingleTypeChildToBuild {
pub fn from_build_or_rule(build_or_rule: &str) -> Self {
pub fn from_build_or_rule(build_or_rule: &str, optional: bool) -> Self {
Self {
build: build_or_rule.to_string(),
var_name: build_or_rule.to_case(Case::Snake),
with: make_build_fn_name(build_or_rule),
optional,
}
}
@ -300,6 +300,11 @@ impl SingleTypeChildToBuild {
pub fn with(&self) -> &str {
&self.with
}
/// If the type should be wrapped in an Option.
pub fn optional(&self) -> bool {
self.optional
}
}
#[derive(Debug)]

View File

@ -64,9 +64,15 @@ fn handle_single_type_child(
let child_ident_mut = format_ident!("{}_mut", single_type_child.var_name());
let child_type_ident = format_ident!("{}", single_type_child.build());
member_names.push(child_ident.clone());
if single_type_child.optional() {
annotated_members.push(quote! {
#child_ident: Option<Box<#child_type_ident>>
});
} else {
annotated_members.push(quote! {
#child_ident: Box<#child_type_ident>
});
})
}
accessors.push(quote! {
pub fn #child_ident(&self) -> &#child_type_ident {
self.#child_ident.as_ref()