This is an automated email from the ASF dual-hosted git repository. kriskras99 pushed a commit to branch fix/union_select in repository https://gitbox.apache.org/repos/asf/avro-rs.git
commit c0965caecafe824cc4010953a808e7e362e3206c Author: default <[email protected]> AuthorDate: Wed Jan 21 13:20:16 2026 +0000 fix: Be more selective when choosing an union when serializing bytes with schema --- avro/src/serde/ser_schema.rs | 70 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/avro/src/serde/ser_schema.rs b/avro/src/serde/ser_schema.rs index 5a092c5..9da58ad 100644 --- a/avro/src/serde/ser_schema.rs +++ b/avro/src/serde/ser_schema.rs @@ -18,7 +18,7 @@ //! Logic for serde-compatible schema-aware serialization //! which writes directly to a `Write` stream -use crate::schema::{InnerDecimalSchema, UuidSchema}; +use crate::schema::{DecimalSchema, InnerDecimalSchema, UuidSchema}; use crate::{ bigdecimal::big_decimal_as_bytes, encode::{encode_int, encode_long}, @@ -1282,15 +1282,33 @@ impl<'s, W: Write> SchemaAwareWriteSerializer<'s, W> { match variant_schema { Schema::String | Schema::Bytes - | Schema::Uuid(_) + | Schema::Uuid(UuidSchema::Bytes | UuidSchema::String) | Schema::BigDecimal - | Schema::Fixed(_) - | Schema::Duration(_) - | Schema::Decimal(_) + | Schema::Decimal(DecimalSchema { + inner: InnerDecimalSchema::Bytes, + .. + }) | Schema::Ref { name: _ } => { encode_int(i as i32, &mut *self.writer)?; return self.serialize_bytes_with_schema(value, variant_schema); } + Schema::Fixed(fixed) | Schema::Uuid(UuidSchema::Fixed(fixed)) + if fixed.size == value.len() => + { + encode_int(i as i32, &mut *self.writer)?; + return self.serialize_bytes_with_schema(value, variant_schema); + } + Schema::Decimal(DecimalSchema { + inner: InnerDecimalSchema::Fixed(fixed), + .. + }) if fixed.size >= value.len() => { + encode_int(i as i32, &mut *self.writer)?; + return self.serialize_bytes_with_schema(value, variant_schema); + } + Schema::Duration(_) if value.len() == 12 => { + encode_int(i as i32, &mut *self.writer)?; + return self.serialize_bytes_with_schema(value, variant_schema); + } _ => { /* skip */ } } } @@ -3549,4 +3567,46 @@ mod tests { Ok(()) } + + #[test] + fn avro_rs_421_serialize_bytes_union_of_fixed() -> TestResult { + #[derive(Serialize, Deserialize)] + #[serde(transparent)] + struct Fixed4 { + #[serde(with = "crate::serde_avro_fixed")] + field: [u8; 4], + } + #[derive(Serialize, Deserialize)] + #[serde(transparent)] + struct Fixed8 { + #[serde(with = "crate::serde_avro_fixed")] + field: [u8; 8], + } + + let schema = Schema::parse_str( + r#"[ + { "name": "fixed4", "type": "fixed", "size": 4 }, + { "name": "fixed8", "type": "fixed", "size": 8 } + ]"#, + ) + .unwrap(); + + let mut buffer: Vec<u8> = Vec::new(); + let names = HashMap::new(); + let mut serializer = SchemaAwareWriteSerializer::new(&mut buffer, &schema, &names, None); + let bytes_written = Fixed4 { + field: [0, 1, 2, 3], + } + .serialize(&mut serializer)?; + assert_eq!(bytes_written, 4); + let bytes_written = Fixed8 { + field: [4, 5, 6, 7, 8, 9, 10, 11], + } + .serialize(&mut serializer)?; + assert_eq!(bytes_written, 8); + + assert_eq!(buffer, &[0, 0, 1, 2, 3, 2, 4, 5, 6, 7, 8, 9, 10, 11][..]); + + Ok(()) + } }
