avro-rs
avro-rs copied to clipboard
Wrong field is parsed when the `"logicalType": "uuid"` value is set on a field
So this is a strange issue. It seems like if "logicalType": "uuid" is set, it parses the value next field instead of the existing one.
Take a look at this example:
use uuid::Uuid;
use std::str::FromStr;
use serde::{Serialize};
use avro_rs::{Reader, Writer, Schema};
#[derive(Debug, Serialize)]
struct Event {
id: Uuid,
event_type: String
}
fn main() {
let raw_schema = r#"
{
"type": "record",
"namespace": "something",
"name": "TimelineEvent",
"fields": [{
"name": "id",
"type": "string",
"logicalType": "uuid"
}, {
"name": "event_type",
"type": "string"
}]
}
"#;
let schema = Schema::parse_str(raw_schema).unwrap();
let e = Event {
id: Uuid::from_str("596a6c76-b398-4458-8b25-e5451850a7da").unwrap(),
event_type: "user_created".to_string()
};
let mut writer = Writer::new(&schema, Vec::new());
writer.append_ser(&e).unwrap();
let serialized = writer.into_inner().unwrap();
let reader = Reader::new(&serialized[..]).unwrap();
for v in reader {
println!("The length of the next field (event_type) is {:?}", &e.event_type.len());
println!("{:?}", v.unwrap());
}
}
Which produces:
Finished dev [unoptimized + debuginfo] target(s) in 1.21s
Running `target/debug/avro-bug-repro`
The length of the next field (event_type) is 12
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ConvertStrToUuid(Error(Parser(InvalidLength { expected: Any([36, 32]), found: 12 })))', src/main.rs:46:28
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Removing the logical type "fixes" this issue, but I guess that's not really the solution.
So the Uuid is actually not getting encoded at all into the payload sadly :( https://github.com/flavray/avro-rs/pull/188 is a workaround, but I think I need to read more about serde first, to see if there is another way to coerce to the correct type.