flavray / avro-rs

Avro client library implementation in Rust
MIT License
169 stars 95 forks source link

Serializing Some(date) gives validation error #167

Open ttencate opened 3 years ago

ttencate commented 3 years ago

Using avro-rs 0.11.0 because 0.12.0 won't compile for me.

use avro_rs::{Schema, Writer};
use serde::Serialize;

#[derive(Serialize)]
struct Foo {
    date: Option<i32>,
}

fn main() {
    let schema = Schema::parse_str(
        r#"{
            "type": "record",
            "name": "Foo",
            "fields": [
                {"name": "date", "type": ["null", {"type": "int", "logicalType": "date"}]}
            ]
        }"#)
        .unwrap();
    let mut writer = Writer::new(&schema, Vec::new());

    writer.append_ser(Foo { date: None }).unwrap(); // This works fine.

    writer.append_ser(Foo { date: Some(42) }).unwrap(); // This returns avro_rs::Error::Validation.
}

I think this happens because UnionSchema::find_schema only looks for a variant that matches the input type exactly:

https://github.com/flavray/avro-rs/blob/de6153ecea6fe660bcf20ff67f47a0b05211b8e1/src/schema.rs#L343-L349

That logic fails here, because the schema contains a Schema::Date variant but the incoming value is a Value::Int. Note that Value::validate handles this case correctly.

ttencate commented 3 years ago

I hacked around this in my fork, but my approach is probably not the best way so I doubt it's worth a PR: https://github.com/ttencate/avro-rs/commit/1c89f55134797e2ed7825f6434cd3f1efc1fe48b

poros commented 3 years ago

Thanks for reporting the bug. As for the compilation, the error should disappear if you can update your rust version.