Skip to content

Commit

Permalink
Merge pull request #76 from ouertani/feat/add_extra_derives
Browse files Browse the repository at this point in the history
feat: add extra derives option
  • Loading branch information
lerouxrgd authored Oct 27, 2024
2 parents a3ebf8e + 57ca634 commit 93babbd
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Options:
--chrono-dates Use chrono::NaiveDateTime for date/timestamps logical types
--derive-builders Derive builders for generated record structs
--derive-schemas Derive AvroSchema for generated record structs
--extra_derives Append extra derive macros list to the generated record structs
-h, --help Print help
-V, --version Print version
```
Expand Down
11 changes: 11 additions & 0 deletions src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ pub struct GeneratorBuilder {
use_chrono_dates: bool,
derive_builders: bool,
derive_schemas: bool,
extra_derives: Vec<String>,
}

impl Default for GeneratorBuilder {
Expand All @@ -296,6 +297,7 @@ impl Default for GeneratorBuilder {
use_chrono_dates: false,
derive_builders: false,
derive_schemas: false,
extra_derives: vec![],
}
}
}
Expand Down Expand Up @@ -351,6 +353,14 @@ impl GeneratorBuilder {
self
}

/// Adds support to derive custom macros.
///
/// Applies to record structs.
pub fn extra_derives(mut self, extra_derives: Vec<String>) -> GeneratorBuilder {
self.extra_derives = extra_derives;
self
}

/// Create a [`Generator`](Generator) with the builder parameters.
pub fn build(self) -> Result<Generator> {
let mut templater = Templater::new()?;
Expand All @@ -360,6 +370,7 @@ impl GeneratorBuilder {
templater.use_chrono_dates = self.use_chrono_dates;
templater.derive_builders = self.derive_builders;
templater.derive_schemas = self.derive_schemas;
templater.extra_derives = self.extra_derives;
Ok(Generator { templater })
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ struct Args {
/// Derive AvroSchema for generated record structs
#[clap(long)]
pub derive_schemas: bool,

/// Extract Derives for generated record structs, comma separated, e.g. `std::fmt::Display,std::string::ToString`
#[clap(long, value_delimiter = ',')]
pub extra_derives: Vec<String>,
}

fn run() -> Result<(), Box<dyn Error>> {
Expand All @@ -70,6 +74,7 @@ fn run() -> Result<(), Box<dyn Error>> {
.use_chrono_dates(args.chrono_dates)
.derive_builders(args.derive_builders)
.derive_schemas(args.derive_schemas)
.extra_derives(args.extra_derives)
.build()?;

g.gen(&source, &mut out)?;
Expand Down
7 changes: 6 additions & 1 deletion src/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub const RECORD_TEMPLATE: &str = r#"
/// {{ doc_line }}
{%- endfor %}
{%- endif %}
#[derive(Debug, PartialEq{%- if is_eq_derivable %}, Eq{%- endif %}, Clone, serde::Deserialize, serde::Serialize{%- if derive_builders %}, derive_builder::Builder {%- endif %}{%- if derive_schemas %}, apache_avro::AvroSchema {%- endif %})]
#[derive(Debug, PartialEq{%- if is_eq_derivable %}, Eq{%- endif %}, Clone, serde::Deserialize, serde::Serialize{%- if derive_builders %}, derive_builder::Builder {%- endif %}{%- if derive_schemas %}, apache_avro::AvroSchema {%- endif %} {%- if extra_derives %}, {{ extra_derives}} {%- endif %})]
{%- if derive_builders %}
#[builder(setter(into))]
{%- endif %}
Expand Down Expand Up @@ -509,6 +509,7 @@ pub struct Templater {
pub use_chrono_dates: bool,
pub derive_builders: bool,
pub derive_schemas: bool,
pub extra_derives: Vec<String>,
}

impl Templater {
Expand All @@ -530,6 +531,7 @@ impl Templater {
use_chrono_dates: false,
derive_builders: false,
derive_schemas: false,
extra_derives: vec![],
})
}

Expand Down Expand Up @@ -599,6 +601,9 @@ impl Templater {
ctx.insert("doc", doc);
ctx.insert("derive_builders", &self.derive_builders);
ctx.insert("derive_schemas", &self.derive_schemas);
if !self.extra_derives.is_empty() {
ctx.insert("extra_derives", &self.extra_derives.join(", "));
}

let mut f = Vec::new(); // field names;
let mut t = HashMap::new(); // field name -> field type
Expand Down
25 changes: 25 additions & 0 deletions tests/generation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,3 +230,28 @@ fn gen_recursive() {
fn gen_interop() {
validate_generation("interop", Generator::new().unwrap());
}

#[test]
fn gen_one_extra_derives() {
validate_generation(
"one_extra_derive",
Generator::builder()
.extra_derives(vec!["std::fmt::Display".to_string()])
.build()
.unwrap(),
);
}

#[test]
fn gen_two_extra_derives() {
validate_generation(
"two_extra_derives",
Generator::builder()
.extra_derives(vec![
"std::fmt::Display".to_string(),
"std::string::ToString".to_string(),
])
.build()
.unwrap(),
);
}
8 changes: 8 additions & 0 deletions tests/schemas/one_extra_derive.avsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "record",
"name": "test",
"fields": [
{"name": "a", "type": "long", "default": 42},
{"name": "b", "type": "string"}
]
}
10 changes: 10 additions & 0 deletions tests/schemas/one_extra_derive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

#[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize, std::fmt::Display)]
pub struct Test {
#[serde(default = "default_test_a")]
pub a: i64,
pub b: String,
}

#[inline(always)]
fn default_test_a() -> i64 { 42 }
8 changes: 8 additions & 0 deletions tests/schemas/two_extra_derives.avsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"type": "record",
"name": "test",
"fields": [
{"name": "a", "type": "long", "default": 42},
{"name": "b", "type": "string"}
]
}
10 changes: 10 additions & 0 deletions tests/schemas/two_extra_derives.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

#[derive(Debug, PartialEq, Eq, Clone, serde::Deserialize, serde::Serialize, std::fmt::Display, std::string::ToString)]
pub struct Test {
#[serde(default = "default_test_a")]
pub a: i64,
pub b: String,
}

#[inline(always)]
fn default_test_a() -> i64 { 42 }

0 comments on commit 93babbd

Please sign in to comment.