Skip to content

Commit 789398e

Browse files
committed
Add an example of a custom codec for collections
1 parent 11ea12c commit 789398e

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,47 @@ class JsonCodecMakerSpec extends VerifyingSpec {
797797
"""["-Infinity","Infinity",0.0,1.0E10]""")
798798
verifyDeserError(codecOfDoubleArray, """["Inf","-Inf"]""", "illegal double, offset: 0x00000005")
799799
}
800+
"serialize and deserialize collection from JSON array or a single value using custom value codec" in {
801+
def customCodecOfList[A](aCodec: JsonValueCodec[A]): JsonValueCodec[List[A]] =
802+
new JsonValueCodec[List[A]] {
803+
def nullValue: List[A] = _root_.scala.Nil
804+
805+
def decodeValue(in: JsonReader, default: List[A]): List[A] =
806+
if (in.isNextToken('[')) {
807+
if (in.isNextToken(']')) default
808+
else {
809+
in.rollbackToken()
810+
val x = List.newBuilder[A]
811+
while ({
812+
x += aCodec.decodeValue(in, aCodec.nullValue)
813+
in.isNextToken(',')
814+
}) ()
815+
if (in.isCurrentToken(']')) x.result()
816+
else in.arrayEndOrCommaError()
817+
}
818+
} else {
819+
in.rollbackToken()
820+
List(aCodec.decodeValue(in, aCodec.nullValue))
821+
}
822+
823+
def encodeValue(x: List[A], out: JsonWriter): _root_.scala.Unit =
824+
if (x.size == 1) aCodec.encodeValue(x.head, out) // FIXME: Use `x.sizeCompare(1) == 0` for Scala 2.13+
825+
else {
826+
out.writeArrayStart()
827+
var y = x
828+
while (y ne _root_.scala.Nil) {
829+
aCodec.encodeValue(y.head, out)
830+
y = y.tail
831+
}
832+
out.writeArrayEnd()
833+
}
834+
}
835+
836+
val codecOfDoubleList = customCodecOfList(make[Double])
837+
verifySerDeser(codecOfDoubleList, List(0.0, 1.0e10), """[0.0,1.0E10]""")
838+
verifySerDeser(codecOfDoubleList, List(3.0), """3.0""")
839+
verifySerDeser(codecOfDoubleList, List(), """[]""")
840+
}
800841
"serialize zoned date time values into a custom format" in {
801842
implicit val customCodecOfZonedDateTime: JsonValueCodec[ZonedDateTime] = new JsonValueCodec[ZonedDateTime] {
802843
private[this] val standardCodec: JsonValueCodec[ZonedDateTime] = JsonCodecMaker.make[ZonedDateTime]

0 commit comments

Comments
 (0)