Skip to content

Commit

Permalink
Improve detecting whether default can be derived
Browse files Browse the repository at this point in the history
This checks if a struct contains a required member for which `Default` is not implemented (Enums or other structs which don't have `Default`). If it does, Default will not be derived for that struct.

Signed-off-by: Aaron Dewes <[email protected]>
  • Loading branch information
AaronDewes committed May 17, 2024
1 parent e4e2aa3 commit 140075b
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 9 deletions.
19 changes: 10 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ impl Kopium {
}
self.print_docstr(&s.docs, "");
if s.is_main_container() {
self.print_derives(s);
self.print_derives(s, &structs);
//root struct gets kube derives unless opted out
if !self.hide_kube {
println!(
Expand Down Expand Up @@ -277,7 +277,7 @@ impl Kopium {
println!("pub struct {} {{", s.name);
}
} else {
self.print_derives(s);
self.print_derives(s, &structs);
let spec_trimmed_name = s.name.as_str().replace(&format!("{}Spec", kind), kind);
if s.is_enum {
println!("pub enum {} {{", spec_trimmed_name);
Expand Down Expand Up @@ -338,23 +338,24 @@ impl Kopium {
}
}

fn print_derives(&self, s: &Container) {
fn print_derives(&self, s: &Container, containers: &[Container]) {
let mut derives = vec!["Serialize", "Deserialize", "Clone", "Debug"];

if s.is_main_container() && !self.hide_kube {
// CustomResource first for root struct
derives.insert(0, "CustomResource");
}
if self.builders {

// TypedBuilder does not work with enums
if self.builders && !s.is_enum {
derives.push("TypedBuilder");
}

for derive in &self.derive {
if s.is_enum && derive.derived_trait == "Default" {
// Need to drop Default from enum as this cannot be derived.
// Enum defaults need to either be manually derived
// or we can insert enum defaults
continue;
if derive.derived_trait == "Default" {
if !s.can_derive_default(containers) {
continue;
}
}

if derive.is_applicable_to(s) && !derives.contains(&derive.derived_trait.as_str()) {
Expand Down
30 changes: 30 additions & 0 deletions src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,36 @@ impl Container {
pub fn contains_conditions(&self) -> bool {
self.members.iter().any(|m| m.type_.contains("Vec<Condition>"))
}

pub fn can_derive_default(&self, containers: &[Container]) -> bool {
if self.is_enum {
// Need to drop Default from enum as this cannot be derived.
// Enum defaults need to either be manually derived
// or we can insert enum defaults
return false;
}

for m in &self.members {
if !m.type_.contains('<')
&& !m.type_.contains("::")
&& m.type_ != "String"
&& m.type_ != "IntOrString"
&& m.type_ != "NaiveDate"
&& m.type_ != "DateTime"
&& m.type_.chars().next().unwrap_or_default().is_uppercase()
{
if containers
.iter()
.find(|c| c.name == m.type_)
.is_some_and(|c| !c.can_derive_default(containers))
{
return false;
}
}
}

true
}
}

impl Container {
Expand Down

0 comments on commit 140075b

Please sign in to comment.