From f8722dad57a42f36ee656621c94fc2c9fa310afa Mon Sep 17 00:00:00 2001 From: Mathias Date: Sat, 3 Dec 2022 15:03:54 +0100 Subject: [PATCH] Fix decoding error on extra members for nullary case classes and objects with MapBasedCodecs, closes #600 --- .../io/bullet/borer/derivation/MapBasedCodecs.scala | 9 +++++++-- .../scala/io/bullet/borer/derivation/MiscSpec.scala | 13 +++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/derivation/src/main/scala/io/bullet/borer/derivation/MapBasedCodecs.scala b/derivation/src/main/scala/io/bullet/borer/derivation/MapBasedCodecs.scala index 2aafc91f..c5c80fec 100644 --- a/derivation/src/main/scala/io/bullet/borer/derivation/MapBasedCodecs.scala +++ b/derivation/src/main/scala/io/bullet/borer/derivation/MapBasedCodecs.scala @@ -246,7 +246,12 @@ object MapBasedCodecs extends DerivationApi { new Deriver[Decoder, T, quotes.type]: def deriveForCaseObject(moduleTermSymbol: Symbol): Expr[Decoder[T]] = - '{ Decoder[T](r => r.readMapClose(r.readMapOpen(0), ${ Ref(moduleTermSymbol).asExprOf[T] })) } + '{ + Decoder[T] { r => + if (r.readMapOpen(0)) while (!r.tryReadBreak()) r.skipElement() + ${ Ref(moduleTermSymbol).asExprOf[T] } + } + } def deriveForCaseClass( tpe: TypeRepr, @@ -443,7 +448,7 @@ object MapBasedCodecs extends DerivationApi { else fail("Case classes mit > 128 fields are not supported") } else '{ - if (count < 0) $r.readBreak() + if (count < 0) while (! $r.tryReadBreak()) $r.skipElement() ${ companionApply(companion, typeArgs(tpe), Nil).asExprOf[T] } } } diff --git a/derivation/src/test/scala/io/bullet/borer/derivation/MiscSpec.scala b/derivation/src/test/scala/io/bullet/borer/derivation/MiscSpec.scala index a571a21c..d4c739a5 100644 --- a/derivation/src/test/scala/io/bullet/borer/derivation/MiscSpec.scala +++ b/derivation/src/test/scala/io/bullet/borer/derivation/MiscSpec.scala @@ -162,4 +162,17 @@ class MiscSpec extends AbstractBorerSpec { | 1| } |""".stripMargin } + + test("Extra members") { + sealed trait Base + case class A(x: Int) extends Base + case class B() extends Base + case object C extends Base + + implicit val baseCodecs: Decoder[Base] = MapBasedCodecs.deriveAllDecoders + + verifyDecoding[Base]("""{"A":{"x":100, "extra": "should be ignored"}}""", A(100)) + verifyDecoding[Base]("""{"B":{"extra": "should be ignored"}}""", B()) + verifyDecoding[Base]("""{"C":{"extra": "should be ignored"}}""", C) + } }