pickling
pickling copied to clipboard
Pickling a complex type as String
Disclaimer: I'm not sure if what I am trying to do could in theory work, because I don't know enough about pickle theory.
I'm trying to pickle a Java class (org.bson.types.ObjectId
) so that its JSON representation yields a String. That works. However, unpickling does not quite work as well because, I think, the field is recognised as String and the JSONPickleReader
does not know what to do (I get a MatchError
). Hinting it with a different type tag than FastTypeTags.String
yields an empty result at pickle-time.
My belief is that the unpickling strategy would be influenced by the knowledge of a type encoded (in the case of JSON) in the $type
field of the pickled format, hence if at unpickle time we know that a field should be of a certain type then there should be a means by which to call for the adequate unpickler. Or is my belief nonsense?
For reference, the working pickling and broken unpickling:
def pickle(picklee: ObjectId, builder: PBuilder): Unit = {
builder.hintStaticallyElidedType()
// this probably needs to hint at ObjectId but then the stringPickler isn't thrilled and returns nothing
builder.hintTag(FastTypeTag.String)
stringPickler.pickle(picklee.toString, builder)
}
def unpickle(tag: String, reader: PReader): Any = {
val oid = stringPickler.unpickle(tag, reader).asInstanceOf[String]
new ObjectId(oid)
}
This may be helpful: https://github.com/sbt/serialization/blob/master/serialization/src/main/scala/sbt/serialization/pickler/JavaExtraPicklers.scala#L39
Thanks for the hint @havocp but I'm afraid the trouble arises before my custom unpickler even has a chance to get called - I tried using a similar approach to the example (pushing hints, pinning them etc. - by the way is there anywhere I could read up on what the meaning of pushing, pinning, unpinning etc. is?) but to no avail, the JSONPickleReader blows up at https://github.com/scala/pickling/blob/e8e6e261a592b364c8d602b11b0174248018a1fa/core/src/main/scala/pickling/json/JSONPickleFormat.scala#L212 (at least this is the line reported in version 0.10, but it seems a bit odd as the type is elided so it shouldn't get there, I will retry with the latest version later on).
My unpickler doesn't seem to get called, at least I can't find a trace of it in the stacktrace.
if you blow up there then I think your goal is to go here instead: https://github.com/scala/pickling/blob/e8e6e261a592b364c8d602b11b0174248018a1fa/core/src/main/scala/pickling/json/JSONPickleFormat.scala#L206
maybe build a small compilable test case to attach here.
there aren't docs for the hints stuff. If I knew what they should say, I'd write them. :-)