2

I am trying to write a custom pickler for a case class which has a List[String] member. I am currently using scala-pickling version 0.10.1

I am aware about the builder.beginCollection method to pickle collections, but I was not able to get any documentation about its use to unpickle. After much reading of the scala-pickler source code I have found some indication on how to use it properly.

Right now I have the following code, which generates, I think the wrong output (about that after the example). I would appreciate either a piece of example code or a link to some documentation.

import scala.pickling._, json._, Defaults._

case class Beta(isSecond : Boolean, notSecond : List[String])

object BetaPickler extends Pickler[Beta] {
    override val tag = FastTypeTag[Beta]

    override def pickle(picklee: Beta, builder: PBuilder): Unit = {
        builder.hintTag(tag) // This is always required
        builder.pinHints()
        builder.beginEntry(picklee)

        builder.putField("isSecond", {
            b => b.hintTag(FastTypeTag.Boolean).beginEntry(picklee.isSecond).endEntry()
        })

        builder.putField("notSecond", { b => {
            b.hintTag(FastTypeTag[String])

            b.beginEntry()
            b.beginCollection(picklee.notSecond.size)

            picklee.notSecond.foreach((item: String) => {

                b.putElement(pb => {
                    pb.hintTag(implicitly[FastTypeTag[String]])
                    stringPickler.pickle(item, pb)
                })
            })

            builder.endCollection()
            builder.endEntry()
        }
        })

        builder.unpinHints()
        builder.endEntry()
    }
}

implicit def pickler: scala.pickling.Pickler[Beta] = BetaPickler

val xBeta : Beta = Beta(true, List("one","three","four"))

So, this is the example code, you can copy :paste it into the REPL, it should work. The problem is in the output JSON, where the notSecond member of the class Beta is not rendered properly. As you can see the notSecond object has an empty "value" member, and the actual "elem" array is outside, immediately after the "notSecond" object, while I would expect it to be inside, in place of that "value" member.

scala> xBeta.pickle
res0: scala.pickling.json.pickleFormat.PickleType =
JSONPickle({
    "$type": "Beta",
    "isSecond": {
        "$type": "scala.Boolean",
        "value": true
    },
    "notSecond": {
        "$type": "java.lang.String",
        "value": "()"
    },
        "elems": [
            {
            "$type": "java.lang.String",
            "value": "one"
        },
            {
            "$type": "java.lang.String",
            "value": "three"
        },
            {
            "$type": "java.lang.String",
            "value": "four"
        }
        ]
})

I would appreciate some comments on the way I am pickling the List collection, and maybe a fix for my example. Thanks a lot!

alva
  • 72
  • 8

0 Answers0