From 68817112a761a154851a862759f6af365c4e8390 Mon Sep 17 00:00:00 2001 From: Ben Plommer Date: Tue, 18 May 2021 16:25:54 +0100 Subject: [PATCH] Fix #351 --- .../core/src/main/scala/vulcan/Codec.scala | 102 ++++++++++-------- 1 file changed, 55 insertions(+), 47 deletions(-) diff --git a/modules/core/src/main/scala/vulcan/Codec.scala b/modules/core/src/main/scala/vulcan/Codec.scala index 1cabf3e1..73a90836 100644 --- a/modules/core/src/main/scala/vulcan/Codec.scala +++ b/modules/core/src/main/scala/vulcan/Codec.scala @@ -1092,60 +1092,68 @@ object Codec extends CodecCompanionCompat { }, (value, schema) => { val schemaTypes = - schema.getType() match { + schema.getType match { case UNION => schema.getTypes.asScala case _ => Seq(schema) } + def decodeNamedContainerType(container: GenericContainer) = { + val altName = + container.getSchema.getName + + val altWriterSchema = + schemaTypes + .find(_.getName == altName) + .toRight(AvroError.decodeMissingUnionSchema(altName)) + + def altMatching = + alts + .find(_.codec.schema.exists { schema => + schema.getType match { + case RECORD | FIXED | ENUM => + schema.getName == altName || schema.getAliases.asScala + .exists(alias => alias == altName || alias.endsWith(s".$altName")) + case _ => false + } + }) + .toRight(AvroError.decodeMissingUnionAlternative(altName)) + + altWriterSchema.flatMap { altSchema => + altMatching.flatMap { alt => + alt.codec + .decode(container, altSchema) + .map(alt.prism.reverseGet) + } + } + } + + def decodeUnnamedType(other: Any) = + alts + .collectFirstSome { alt => + alt.codec.schema + .traverse { altSchema => + val altName = altSchema.getName + schemaTypes + .find(_.getName == altName) + .flatMap { schema => + alt.codec + .decode(other, schema) + .map(alt.prism.reverseGet) + .toOption + } + } + } + .getOrElse { + Left(AvroError.decodeExhaustedAlternatives(other)) + } + value match { case container: GenericContainer => - val altName = - container.getSchema.getName - - val altWriterSchema = - schemaTypes - .find(_.getName == altName) - .toRight(AvroError.decodeMissingUnionSchema(altName)) - - def altMatching = - alts - .find(_.codec.schema.exists { schema => - schema.getType match { - case RECORD | FIXED | ENUM => - schema.getName == altName || schema.getAliases.asScala - .exists(alias => alias == altName || alias.endsWith(s".$altName")) - case _ => false - } - }) - .toRight(AvroError.decodeMissingUnionAlternative(altName)) - - altWriterSchema.flatMap { altSchema => - altMatching.flatMap { alt => - alt.codec - .decode(container, altSchema) - .map(alt.prism.reverseGet) - } + container.getSchema.getType match { + case RECORD | FIXED | ENUM => decodeNamedContainerType(container) + case _ => decodeUnnamedType(container) } - - case other => - alts - .collectFirstSome { alt => - alt.codec.schema - .traverse { altSchema => - val altName = altSchema.getName - schemaTypes - .find(_.getName == altName) - .flatMap { schema => - alt.codec - .decode(other, schema) - .map(alt.prism.reverseGet) - .toOption - } - } - } - .getOrElse { - Left(AvroError.decodeExhaustedAlternatives(other)) - } + case other => decodeUnnamedType(other) } } )