diff --git a/src/Chr.Avro.Binary/BinaryDeserializerBuilder.cs b/src/Chr.Avro.Binary/BinaryDeserializerBuilder.cs index 49d738e1a..4c4d911ea 100644 --- a/src/Chr.Avro.Binary/BinaryDeserializerBuilder.cs +++ b/src/Chr.Avro.Binary/BinaryDeserializerBuilder.cs @@ -1726,13 +1726,8 @@ public override Delegate BuildDelegate(TypeResolution resolution, Schema schema, var assignments = recordSchema.Fields.Select(field => { var match = recordResolution.Fields.SingleOrDefault(f => f.Name.IsMatch(field.Name)); - - // ensure that an integer is used as the surrogate for enum fields: - var fieldSchema = match == null && field.Type is EnumSchema - ? new LongSchema() - : field.Type; - - var type = match?.Type ?? CreateSurrogateType(fieldSchema); + var fieldSchema = match == null ? CreateSurrogateSchema(field.Type) : field.Type; + var type = match == null ? CreateSurrogateType(fieldSchema) : match.Type; Expression action = null; @@ -1772,17 +1767,48 @@ public override Delegate BuildDelegate(TypeResolution resolution, Schema schema, return compiled; } + /// + /// Creates a schema that can be used to deserialize missing record fields. + /// + /// + /// The schema to alter. + /// + /// + /// A schema that can be mapped to a surrogate type. + /// + protected virtual Schema CreateSurrogateSchema(Schema schema) + { + switch (schema) + { + case ArraySchema array: + return new ArraySchema(CreateSurrogateSchema(array.Item)); + + case EnumSchema _: + return new LongSchema(); + + case MapSchema map: + return new MapSchema(CreateSurrogateSchema(map.Value)); + + case UnionSchema union: + return new UnionSchema(union.Schemas.Select(CreateSurrogateSchema).ToList()); + + default: + return schema; + } + } + /// /// Creates a type that can be used to deserialize missing record fields. /// /// - /// The schema to generate a compatible type for. + /// The schema to select a compatible type for. /// /// /// if the schema is an array schema (or a union schema /// containing only array/null schemas), if the /// schema is a map schema (or a union schema containing only map/null schemas), and - /// otherwise. + /// otherwise. + /// protected virtual Type CreateSurrogateType(Schema schema) { var schemas = schema is UnionSchema union