-
Notifications
You must be signed in to change notification settings - Fork 79
Add support for specialized tuples #428
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package scala.pickling.util | ||
|
||
object ClassMapper { | ||
|
||
val specializedTuplesTemplate = | ||
Vector( | ||
"$mcII$sp", "$mcIJ$sp", "$mcID$sp", "$mcIZ$sp", "$mcJI$sp", "$mcJJ$sp", | ||
"$mcJD$sp", "$mcJC$sp", "$mcJZ$sp", "$mcDI$sp", "$mcDJ$sp", "$mcDD$sp", | ||
"$mcDC$sp", "$mcDZ$sp", "$mcCI$sp", "$mcCJ$sp", "$mcCD$sp", "$mcCC$sp", | ||
"$mcCZ$sp", "$mcZI$sp", "$mcZJ$sp", "$mcZD$sp", "$mcZC$sp", "$mcZZ$sp" | ||
) | ||
|
||
/* Map specialized classes to classes. Canonical use case: tuples. | ||
* We map classes instead of strings to check at runtime that they exist. */ | ||
val specialMappingClasses: Map[Class[_], Class[_]] = | ||
mapSpecializedTuplesFor("scala.Tuple2") // add also other special cases | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We may be able to make this more generic, i forget the rules fo r specialization mangling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure thing! Actually, I'd like to make it more generic, but first i think we should find another compelling use case 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've found out how specialization mangling works, but i think we shouldn't include it now and wait for a more compelling use case. |
||
|
||
def specializedTupleNamesFor(tupleClassName: String): Vector[String] = | ||
specializedTuplesTemplate.map(tupleClassName + _) | ||
|
||
def mapSpecializedTuplesFor(tupleClassName: String): Map[Class[_], Class[_]] = { | ||
val tupleClass = Class.forName(tupleClassName) | ||
specializedTupleNamesFor(tupleClassName) | ||
.map(Class.forName).map(_ -> tupleClass).toMap | ||
} | ||
|
||
@inline def isSpecializedClass(specialized: Class[_], clazz: Class[_]) = | ||
specialMappingClasses.get(specialized).exists(_ == clazz) | ||
|
||
def areSameClasses(clazz: Class[_], clazzT: Class[_]): Boolean = | ||
clazz == clazzT || isSpecializedClass(clazz, clazzT) | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package scala.pickling.generation.pickler | ||
|
||
import org.scalatest.FunSuite | ||
|
||
import scala.pickling._ | ||
import Defaults._ | ||
import json._ | ||
import scala.pickling.util.ClassMapper | ||
import static._ | ||
|
||
class Tuple2Pickler extends FunSuite { | ||
|
||
test("pickle/unpickle (Int, String)") { | ||
val t = (1, "") | ||
val t2 = t.pickle.unpickle[(Int, String)] | ||
assert(t === t2) | ||
} | ||
|
||
test("pickle/unpickle any specialized tuple like (Int, Int)") { | ||
val t = (1, 2) | ||
val clz = classOf[(Int, Int)] | ||
val clzT = t.getClass | ||
println(ClassMapper.areSameClasses(clzT, clz)) | ||
val t2 = t.pickle.unpickle[(Int, Int)] | ||
assert(t === t2) | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this already handled in the CaseDef?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but they're used for different use cases. The one that solves my problem is this one, but for the sake of correctness I decided to put it in the
CaseDef
as well. IIRC, this one takes care of the superclass, the case def of the subclasses.