diff --git a/modules/core/src/main/scala/vulcan/Codec.scala b/modules/core/src/main/scala/vulcan/Codec.scala index e1654054..783902e8 100644 --- a/modules/core/src/main/scala/vulcan/Codec.scala +++ b/modules/core/src/main/scala/vulcan/Codec.scala @@ -401,14 +401,13 @@ object Codec extends CodecCompanionCompat { else Left(AvroError.encodeSymbolNotInSchema(symbol, symbols, typeName)) }, { - case (genericEnum: GenericEnumSymbol[_], schema) => - val symbols = schema.getEnumSymbols().asScala.toList + case (genericEnum: GenericEnumSymbol[_], _) => val symbol = genericEnum.toString() if (symbols.contains(symbol)) decode(symbol) else - Left(AvroError.decodeSymbolNotInSchema(symbol, symbols, typeName)) + default.toRight(AvroError.decodeSymbolNotInSchema(symbol, symbols, typeName)) } ) } diff --git a/modules/core/src/test/scala/vulcan/CodecSpec.scala b/modules/core/src/test/scala/vulcan/CodecSpec.scala index f3b74d04..75caf871 100644 --- a/modules/core/src/test/scala/vulcan/CodecSpec.scala +++ b/modules/core/src/test/scala/vulcan/CodecSpec.scala @@ -597,14 +597,26 @@ final class CodecSpec extends BaseSpec with CodecSpecHelpers { ) } - it("should error if encoded value is not a schema symbol") { - assertDecodeError[SealedTraitEnum]( + it("should return default value if encoded value is not a schema symbol") { + assertDecodeIs[SealedTraitEnum]( new GenericData.EnumSymbol( SchemaFactory.enumeration("vulcan.examples.SealedTraitEnum", Array("symbol")), "symbol" ), + Right(FirstInSealedTraitEnum), + Some(unsafeSchema[SealedTraitEnum]) + ) + } + + it("should error if encoded value is not a schema symbol and there is no default value") { + assertDecodeError[SealedTraitEnumNoDefault]( + new GenericData.EnumSymbol( + SchemaFactory + .enumeration("vulcan.examples.SealedTraitEnumNoDefault", Array("symbol")), + "symbol" + ), unsafeSchema[SealedTraitEnum], - "symbol is not part of schema symbols [first, second] for type vulcan.examples.SealedTraitEnum" + "symbol is not part of schema symbols [first, second] for type vulcan.examples.SealedTraitEnumNoDefault" ) } diff --git a/modules/core/src/test/scala/vulcan/examples/SealedTraitEnumNoDefault.scala b/modules/core/src/test/scala/vulcan/examples/SealedTraitEnumNoDefault.scala new file mode 100644 index 00000000..a8466607 --- /dev/null +++ b/modules/core/src/test/scala/vulcan/examples/SealedTraitEnumNoDefault.scala @@ -0,0 +1,39 @@ +package vulcan.examples + +import cats.Eq +import org.scalacheck.{Arbitrary, Gen} +import vulcan.{AvroError, Codec, Props} + +sealed trait SealedTraitEnumNoDefault + +object SealedTraitEnumNoDefault { + implicit final val arbitrary: Arbitrary[SealedTraitEnumNoDefault] = + Arbitrary(Gen.oneOf(FirstInSealedTraitEnumNoDefault, SecondInSealedTraitEnumNoDefault)) + + implicit final val eq: Eq[SealedTraitEnumNoDefault] = + Eq.fromUniversalEquals + + implicit final val codec: Codec[SealedTraitEnumNoDefault] = + Codec.enumeration( + name = "SealedTraitEnumNoDefault", + namespace = "vulcan.examples", + symbols = List("first", "second"), + aliases = List("first", "second"), + doc = Some("documentation"), + default = None, + encode = { + case FirstInSealedTraitEnumNoDefault => "first" + case SecondInSealedTraitEnumNoDefault => "second" + }, + decode = { + case "first" => Right(FirstInSealedTraitEnumNoDefault) + case "second" => Right(SecondInSealedTraitEnumNoDefault) + case other => Left(AvroError(other)) + }, + props = Props.one("custom1", 10).add("custom2", "value2") + ) +} + +case object FirstInSealedTraitEnumNoDefault extends SealedTraitEnumNoDefault + +case object SecondInSealedTraitEnumNoDefault extends SealedTraitEnumNoDefault