Skip to content

Commit

Permalink
Use serde_bytes crate for serializing Schema::Bytes (#36)
Browse files Browse the repository at this point in the history
Reported at Apache Avro user@ mailing list: https://lists.apache.org/thread/cmkc6b7g5pqh63odtrj5vg502w7o4n4h

Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>

Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
  • Loading branch information
martin-g authored Aug 30, 2022
1 parent 59b541c commit 114b4e5
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 1 deletion.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ glob = "0.3"
heck = "0.4"
lazy_static = "1"
serde = { version = "1", features = ["serde_derive"] }
serde_bytes = "0.11"
serde_json = "1"
tera = { version = "1", default-features = false }
thiserror = "1"
Expand Down
2 changes: 1 addition & 1 deletion src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl Generator {
}

/// Generates Rust code from an Avro schema [`Source`](Source).
/// Writes all generated types to the ouput.
/// Writes all generated types to the output.
pub fn gen(&self, source: &Source, output: &mut impl Write) -> Result<()> {
match source {
Source::Schema(schema) => {
Expand Down
13 changes: 13 additions & 0 deletions src/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub struct {{ name }} {
{%- if defaults is containing(f) and not fields | length == defaults | length %}
#[serde(default = "default_{{ name | lower }}_{{ f | lower | trim_start_matches(pat="r#") }}")]
{%- endif %}
{%- if bytes is containing(f) %}
#[serde(with = "serde_bytes")]
{%- endif %}
pub {{ f }}: {{ type }},
{%- endfor %}
}
Expand Down Expand Up @@ -409,6 +412,7 @@ impl Templater {
let mut t = HashMap::new(); // field name -> field type
let mut o = HashMap::new(); // field name -> original name
let mut d = HashMap::new(); // field name -> default value
let mut b = HashSet::new(); // bytes fields;

let mut fields_by_pos = fields.iter().clone().collect::<Vec<_>>();
fields_by_pos.sort_by_key(|f| f.position);
Expand Down Expand Up @@ -482,6 +486,7 @@ impl Templater {
}

Schema::Bytes => {
b.insert(name_std.clone());
f.push(name_std.clone());
t.insert(name_std.clone(), "Vec<u8>".to_string());
if let Some(default) = default {
Expand Down Expand Up @@ -599,6 +604,13 @@ impl Templater {
let default = self.parse_default(schema, gen_state, default)?;
d.insert(name_std.clone(), default);
}
union.variants().iter().any(|variant| {
if let Schema::Bytes = variant {
b.insert(name_std.clone());
return true;
}
false
});
}

Schema::Null => err!("Invalid use of Schema::Null")?,
Expand All @@ -609,6 +621,7 @@ impl Templater {
ctx.insert("types", &t);
ctx.insert("originals", &o);
ctx.insert("defaults", &d);
ctx.insert("bytes", &b);
ctx.insert("is_eq_derivable", &gen_state.is_eq_derivable(schema));
if self.nullable {
ctx.insert("nullable", &true);
Expand Down
1 change: 1 addition & 0 deletions tests/schemas/record.avsc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{"name": "favoriteNumber", "type": "int", "default": 7},
{"name": "likes_pizza", "type": "boolean", "default": false},
{"name": "b", "type": "bytes", "default": "\u00FF"},
{"name": "union_b", "type": ["null", "bytes"], "default": null},
{"name": "a-bool", "type": {"type": "array", "items": "boolean"}, "default": [true, false]},
{"name": "a-i32", "type": {"type": "array", "items": "int"}, "default": [12, -1]},
{"name": "m-f64", "type": {"type": "map", "values": "double"}}
Expand Down
7 changes: 7 additions & 0 deletions tests/schemas/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ pub struct User {
#[serde(default = "default_user_likes_pizza")]
pub likes_pizza: bool,
#[serde(default = "default_user_b")]
#[serde(with = "serde_bytes")]
pub b: Vec<u8>,
#[serde(default = "default_user_union_b")]
#[serde(with = "serde_bytes")]
pub union_b: Option<Vec<u8>>,
#[serde(rename = "a-bool")]
#[serde(default = "default_user_a_bool")]
pub a_bool: Vec<bool>,
Expand All @@ -28,6 +32,9 @@ fn default_user_likes_pizza() -> bool { false }
#[inline(always)]
fn default_user_b() -> Vec<u8> { vec![195, 191] }

#[inline(always)]
fn default_user_union_b() -> Option<Vec<u8>> { None }

#[inline(always)]
fn default_user_a_bool() -> Vec<bool> { vec![true, false] }

Expand Down

0 comments on commit 114b4e5

Please sign in to comment.