diff --git a/lang/rust/avro/src/encode.rs b/lang/rust/avro/src/encode.rs index 94436b86f72..e8080f04be1 100644 --- a/lang/rust/avro/src/encode.rs +++ b/lang/rust/avro/src/encode.rs @@ -196,33 +196,39 @@ pub(crate) fn encode_internal>( }); } } - 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); diff --git a/lang/rust/avro/tests/schema.rs b/lang/rust/avro/tests/schema.rs index 00be0ab01c8..58e95e8cc43 100644 --- a/lang/rust/avro/tests/schema.rs +++ b/lang/rust/avro/tests/schema.rs @@ -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}, @@ -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, @@ -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::(de_value)?; + + assert_eq!(record, deserialized_record); Ok(()) }