Skip to content

Commit

Permalink
AVRO-3821: [Rust] Encoding records should follow the schema (#2417)
Browse files Browse the repository at this point in the history
When encoding Value::Record the logic should use the order of the fields
in the schema instead of the order in the Value::Record

Signed-off-by: Martin Tzvetanov Grigorov <[email protected]>
  • Loading branch information
martin-g authored Aug 4, 2023
1 parent 16ae895 commit d05ca14
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 16 deletions.
34 changes: 20 additions & 14 deletions lang/rust/avro/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,33 +196,39 @@ pub(crate) fn encode_internal<S: Borrow<Schema>>(
});
}
}
Value::Record(fields) => {
Value::Record(value_fields) => {
if let Schema::Record(RecordSchema {
ref name,
fields: ref schema_fields,
ref lookup,
..
}) = *schema
{
let record_namespace = name.fully_qualified_name(enclosing_namespace).namespace;
for (name, value) in fields.iter() {
match lookup.get(name) {
Some(idx) => {
encode_internal(
value,
&schema_fields[*idx].schema,
names,
&record_namespace,
buffer,
)?;
}

let mut lookup = HashMap::new();
value_fields.iter().for_each(|(name, field)| {
lookup.insert(name, field);
});

for schema_field in schema_fields.iter() {
let name = &schema_field.name;
let value = match lookup.get(name) {
Some(value) => value,
None => {
return Err(Error::NoEntryInLookupTable(
name.clone(),
format!("{lookup:?}"),
));
}
}
};

encode_internal(
value,
&schema_field.schema,
names,
&record_namespace,
buffer,
)?;
}
} else {
error!("invalid schema type for Record: {:?}", schema);
Expand Down
11 changes: 9 additions & 2 deletions lang/rust/avro/tests/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use std::io::{Cursor, Read};

use apache_avro::{
from_avro_datum, from_value,
schema::{EnumSchema, FixedSchema, Name, RecordField, RecordSchema},
to_avro_datum, to_value,
types::{Record, Value},
Expand Down Expand Up @@ -1452,7 +1453,7 @@ fn avro_old_issue_47() -> TestResult {

use serde::{Deserialize, Serialize};

#[derive(Deserialize, Serialize)]
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq)]
pub struct MyRecord {
b: String,
a: i64,
Expand All @@ -1463,7 +1464,13 @@ fn avro_old_issue_47() -> TestResult {
a: 1,
};

let _ = to_avro_datum(&schema, to_value(record)?)?;
let ser_value = to_value(record.clone())?;
let serialized_bytes = to_avro_datum(&schema, ser_value)?;

let de_value = &from_avro_datum(&schema, &mut &*serialized_bytes, None)?;
let deserialized_record = from_value::<MyRecord>(de_value)?;

assert_eq!(record, deserialized_record);
Ok(())
}

Expand Down

0 comments on commit d05ca14

Please sign in to comment.