Skip to content

Commit

Permalink
factor out builders into Output::builder_fields
Browse files Browse the repository at this point in the history
Signed-off-by: clux <[email protected]>
  • Loading branch information
clux committed May 3, 2022
1 parent 726664e commit 68203ce
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 17 deletions.
3 changes: 3 additions & 0 deletions src/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ fn analyze_enum_properties(
type_: rust_type,
name: name.to_string(),
serde_annot: vec![],
extra_annot: vec![],
docs: member_doc,
})
}
Expand Down Expand Up @@ -308,6 +309,7 @@ fn analyze_object_properties(
type_: rust_type,
name: key.to_string(),
serde_annot: vec![],
extra_annot: vec![],
docs: member_doc,
})
} else {
Expand All @@ -320,6 +322,7 @@ fn analyze_object_properties(
"default".into(),
"skip_serializing_if = \"Option::is_none\"".into(),
],
extra_annot: vec![],
docs: member_doc,
})
// TODO: must capture `default` key here instead of blindly using serde default
Expand Down
21 changes: 7 additions & 14 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,11 +184,10 @@ impl Kopium {

if let Some(schema) = data {
log::debug!("schema: {}", serde_json::to_string_pretty(&schema)?);
let mut output = analyze(schema, &kind)?;
if self.rust_case {
output = output.rename();
}
let structs = output.0;
let structs = analyze(schema, &kind)?
.rename(self.rust_case)
.builder_fields(self.builders)
.0;

if !self.hide_prelude {
self.print_prelude(&structs);
Expand Down Expand Up @@ -243,16 +242,10 @@ impl Kopium {
} else {
format_ident!("{}", m.name)
};
let spec_trimmed_type = m.type_.as_str().replace(&format!("{}Spec", kind), &kind);
if self.builders {
if spec_trimmed_type.starts_with("Option<") {
println!("#[builder(default, setter(strip_option))]");
} else if spec_trimmed_type.starts_with("Vec<")
|| spec_trimmed_type.starts_with("BTreeMap<")
{
println!("#[builder(default)]");
}
for annot in m.extra_annot {
println!(" {}", annot);
}
let spec_trimmed_type = m.type_.as_str().replace(&format!("{}Spec", kind), &kind);
if s.is_enum {
// NB: only supporting plain enumerations atm, not oneOf
println!(" {},", safe_name);
Expand Down
38 changes: 35 additions & 3 deletions src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ pub struct Member {
///
/// The `rename` attribute is only set if `Container::rename` is called.
pub serde_annot: Vec<String>,
/// Additional field level annotations
///
/// This is currently used by optional builders.
pub extra_annot: Vec<String>,
/// Documentation properties extracted from the property
pub docs: Option<String>,
}

Expand Down Expand Up @@ -77,16 +82,43 @@ impl Container {
}
}
}

/// Add builder annotations
pub fn builder_fields(&mut self) {
for m in &mut self.members {
if m.type_.starts_with("Option<") {
m.extra_annot
.push("#[builder(default, setter(strip_option))]".to_string());
} else if m.type_.starts_with("Vec<") || m.type_.starts_with("BTreeMap<") {
m.extra_annot.push("#[builder(default)]".to_string());
}
}
}
}

impl Output {
/// Rename all structs and all all their members to rust conventions
///
/// Converts [*].members[*].name to snake_case for structs, PascalCase for enums,
/// and adds a serde(rename = "orig_name") annotation to `serde_annot`.
pub fn rename(mut self) -> Self {
for c in &mut self.0 {
c.rename()
pub fn rename(mut self, rust_case: bool) -> Self {
if rust_case {
for c in &mut self.0 {
c.rename()
}
}
self
}

/// Add builders to all output members
///
/// Adds #[builder(default, setter(strip_option))] to all option types.
/// Adds #[builder(default)] to required vec and btreemaps.
pub fn builder_fields(mut self, builders: bool) -> Self {
if builders {
for c in &mut self.0 {
c.builder_fields()
}
}
self
}
Expand Down

0 comments on commit 68203ce

Please sign in to comment.