Skip to content

Commit e948fb9

Browse files
committed
Add a custom codec example to handle 2 subhierarchies of ADT with 2 different discriminator field names
1 parent a7d6247 commit e948fb9

File tree

1 file changed

+54
-2
lines changed

1 file changed

+54
-2
lines changed

jsoniter-scala-macros/shared/src/test/scala/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMakerSpec.scala

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ package com.github.plokhotnyuk.jsoniter_scala.macros
33
import java.nio.charset.StandardCharsets.UTF_8
44
import java.time._
55
import java.util.{Objects, UUID}
6-
import com.github.plokhotnyuk.jsoniter_scala.core._
6+
import com.github.plokhotnyuk.jsoniter_scala.core.{JsonValueCodec, _}
77
import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker._
88
import org.scalatest.exceptions.TestFailedException
9+
910
import java.util.concurrent.ThreadLocalRandom
1011
import scala.annotation.switch
1112
import scala.util.control.NonFatal
@@ -2617,6 +2618,54 @@ class JsonCodecMakerSpec extends VerifyingSpec {
26172618

26182619
verifySerDeser(make[List[Base]], List(A(1), B("VVV")), """[{"type":"A","a":1},{"type":"B","b":"VVV"}]""")
26192620
}
2621+
"serialize and deserialize ADT hierarchy with a custom codec that handles different dicriminator field names" in {
2622+
sealed trait T
2623+
2624+
sealed trait T1 extends T
2625+
2626+
object T1 {
2627+
case object T11 extends T1
2628+
2629+
implicit val codec: JsonValueCodec[T1] =
2630+
make(CodecMakerConfig.withDiscriminatorFieldName(_root_.scala.Some("discriminator1")))
2631+
}
2632+
2633+
sealed trait T2 extends T
2634+
2635+
object T2 {
2636+
case object T22 extends T2
2637+
2638+
implicit val codec: JsonValueCodec[T2] =
2639+
make(CodecMakerConfig.withDiscriminatorFieldName(_root_.scala.Some("discriminator2")))
2640+
}
2641+
2642+
implicit val codecOfT: JsonValueCodec[T] = new JsonValueCodec[T] {
2643+
override def decodeValue(in: JsonReader, default: T): T = {
2644+
in.setMark()
2645+
if (in.isNextToken('{')) {
2646+
if (in.skipToKey("discriminator1")) {
2647+
in.rollbackToMark()
2648+
T1.codec.decodeValue(in, T1.codec.nullValue)
2649+
} else {
2650+
in.rollbackToMark()
2651+
T2.codec.decodeValue(in, T2.codec.nullValue)
2652+
}
2653+
} else {
2654+
in.resetMark()
2655+
in.readNullOrTokenError(default, '{')
2656+
}
2657+
}
2658+
2659+
override def encodeValue(x: T, out: JsonWriter): _root_.scala.Unit = x match {
2660+
case t1: T1 => T1.codec.encodeValue(t1, out)
2661+
case t2: T2 => T2.codec.encodeValue(t2, out)
2662+
}
2663+
2664+
override def nullValue: T = null.asInstanceOf[T]
2665+
}
2666+
2667+
verifySerDeser(make[List[T]], List(T1.T11, T2.T22), """[{"discriminator1":"T11"},{"discriminator2":"T22"}]""")
2668+
}
26202669
"deserialize ADTs with a custom handler of unknown type" in {
26212670
def adtCodecWithUnknownKindHandler[A](knownKinds: Set[String], codec: JsonValueCodec[A],
26222671
handler: String => A): JsonValueCodec[A] =
@@ -2632,7 +2681,10 @@ class JsonCodecMakerSpec extends VerifyingSpec {
26322681
in.skip()
26332682
handler(kind)
26342683
}
2635-
} else in.readNullOrTokenError(default, '{')
2684+
} else {
2685+
in.resetMark()
2686+
in.readNullOrTokenError(default, '{')
2687+
}
26362688
}
26372689

26382690
override def encodeValue(x: A, out: JsonWriter): _root_.scala.Unit = codec.encodeValue(x, out)

0 commit comments

Comments
 (0)