Skip to content

Commit 5047973

Browse files
committed
Add support of Scala 3 tuples with arities greater than 22
1 parent 3768da2 commit 5047973

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

jsoniter-scala-macros/shared/src/main/scala-3/com/github/plokhotnyuk/jsoniter_scala/macros/JsonCodecMaker.scala

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,16 @@ object JsonCodecMaker {
777777

778778
def isTuple(tpe: TypeRepr): Boolean = tpe <:< TypeRepr.of[Tuple]
779779

780+
def isTupleXXL(tpe: TypeRepr): Boolean = tpe match {
781+
case AppliedType(tTpe, _) if tTpe =:= TypeRepr.of[*:] => true
782+
case _ => false
783+
}
784+
785+
def tupleXXLTypeArgs(tpe: TypeRepr): List[TypeRepr] = tpe match {
786+
case AppliedType(_, List(typeArg, tail)) => typeArg.dealias :: tupleXXLTypeArgs(tail)
787+
case _ => Nil
788+
}
789+
780790
def valueClassValueSymbol(tpe: TypeRepr): Symbol = tpe.typeSymbol.fieldMembers.head
781791

782792
def valueClassValueType(tpe: TypeRepr): TypeRepr = tpe.memberType(valueClassValueSymbol(tpe)).dealias
@@ -2627,7 +2637,10 @@ object JsonCodecMaker {
26272637
} else $in.readNullOrTokenError($default, '"')
26282638
}
26292639
} else if (isTuple(tpe)) withDecoderFor(methodKey, default, in) { (in, default) =>
2630-
val indexedTypes = typeArgs(tpe)
2640+
val isXXL = isTupleXXL(tpe)
2641+
val indexedTypes =
2642+
if (isXXL) tupleXXLTypeArgs(tpe)
2643+
else typeArgs(tpe)
26312644
val valDefs = indexedTypes.map {
26322645
var i = 0
26332646
te =>
@@ -2646,9 +2659,13 @@ object JsonCodecMaker {
26462659
ValDef(sym, Some(rhs.asTerm.changeOwner(sym)))
26472660
}
26482661
val readCreateBlock = Block(valDefs, '{
2649-
if ($in.isNextToken(']')) {
2650-
${Apply(TypeApply(Select.unique(New(Inferred(tpe)), "<init>"),
2651-
indexedTypes.map(x => Inferred(x))), valDefs.map(x => Ref(x.symbol))).asExpr}
2662+
if ($in.isNextToken(']')) ${
2663+
if (isXXL) {
2664+
Expr.ofTupleFromSeq(valDefs.map(x => Ref(x.symbol).asExprOf[Any]))
2665+
} else {
2666+
Apply(TypeApply(Select.unique(New(Inferred(tpe)), "<init>"),
2667+
indexedTypes.map(x => Inferred(x))), valDefs.map(x => Ref(x.symbol))).asExpr
2668+
}
26522669
} else $in.arrayEndError()
26532670
}.asTerm)
26542671
'{
@@ -3093,13 +3110,23 @@ object JsonCodecMaker {
30933110
else '{ $out.writeNonEscapedAsciiVal(($tx.name: String)) }
30943111
}
30953112
} else if (isTuple(tpe)) withEncoderFor(methodKey, m, out) { (out, x) =>
3096-
val writeFields = typeArgs(tpe).map {
3113+
val isXXL = isTupleXXL(tpe)
3114+
val indexedTypes =
3115+
if (isXXL) tupleXXLTypeArgs(tpe)
3116+
else typeArgs(tpe)
3117+
val writeFields = indexedTypes.map {
30973118
var i = 0
30983119
te =>
30993120
i += 1
31003121
te.asType match
31013122
case '[t] =>
3102-
genWriteVal(Select.unique(x.asTerm, "_" + i).asExprOf[t], te :: types, isStringified, None, out).asTerm
3123+
val select =
3124+
if (isXXL) {
3125+
val getter =
3126+
Select.unique(x.asTerm, "productElement").appliedTo(Literal(IntConstant(i - 1))).asExprOf[Any]
3127+
'{ $getter.asInstanceOf[t] }.asExprOf[t]
3128+
} else Select.unique(x.asTerm, "_" + i).asExprOf[t]
3129+
genWriteVal(select, te :: types, isStringified, None, out).asTerm
31033130
}
31043131
if (writeFields.isEmpty) fail(s"Expected that ${tpe.show} should be an applied type")
31053132
Block('{ $out.writeArrayStart() }.asTerm :: writeFields, '{ $out.writeArrayEnd() }.asTerm).asExprOf[Unit]

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@ class JsonCodecMakerNewTypeSpec extends VerifyingSpec {
5757
val codecOfIArrays = make[IArrays]
5858

5959
"JsonCodecMaker.make generate codecs which" should {
60+
"serialize and deserialize Scala 3 tuples with arities greater than 22" in {
61+
verifySerDeser(make[(Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, Int, String)],
62+
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, "24"),
63+
"""[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,"24"]""")
64+
}
6065
"serialize and deserialize Scala 3 immutable array" in {
6166
val json = """{"aa":[[1,2],[3,4]],"a":[1,2,3,4]}"""
6267
val iArrays = IArrays(IArray(IArray[Int](1, 2), IArray[Int](3, 4)), IArray[BigInt](1, 2, 3, 4))

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import java.util.{Objects, UUID}
66
import com.github.plokhotnyuk.jsoniter_scala.core.{JsonValueCodec, _}
77
import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker._
88
import org.scalatest.exceptions.TestFailedException
9-
109
import java.util.concurrent.ThreadLocalRandom
1110
import scala.annotation.switch
1211
import scala.util.control.NonFatal

0 commit comments

Comments
 (0)