Scala Pickling: Writing a custom pickler / unpickler for nested structures -


i'm trying write custom spickler / unpickler pair work around current limitations of scala-pickling. data type i'm trying pickle case class, of fields have own spickler , unpickler instances. i'd use these instances in custom pickler, don't know how.

here's example of mean:

// here's class want custom spickler / unpickler. // 1 of fields can pickled, i'd reuse logic. case class myclass[a: spickler: unpickler: fasttypetag](mystring: string, a: a)  // here's custom pickler. class myclasspickler[a: spickler: unpickler: fasttypetag](   implicit val format: pickleformat) extends spickler[myclass[a]] unpickler[myclass[a]] {   override def pickle(     picklee: myclass[a],     builder: pbuilder) {     builder.beginentry(picklee)      // here save `mystring` in custom way.     builder.putfield(       "myspecialpickler",       b => b.hinttag(fasttypetag.scalastring).beginentry(         picklee.mystring).endentry())      // need save `a`, has implicit spickler.     // how use it?      builder.endentry()   }    override def unpickle(     tag: => fasttypetag[_],     reader: preader): myclass[a] = {     reader.beginentry()      // first read string.     val mystring = reader.readfield("myspecialpickler").unpickle[string]      // need read `a`, has implicit unpickler.     // how use it?     val a: = ???      reader.endentry()      myclass(mystring, a)   } } 

i appreciate working example. thanks!

here working example:

case class myclass[a](mystring: string, a: a) 

note type parameter of myclass not need context bounds. custom pickler class needs corresponding implicits:

class myclasspickler[a](implicit val format: pickleformat, atypetag: fasttypetag[a],                                      apickler: spickler[a], aunpickler: unpickler[a])   extends spickler[myclass[a]] unpickler[myclass[a]] {    private val stringunpickler = implicitly[unpickler[string]]    override def pickle(picklee: myclass[a], builder: pbuilder) = {     builder.beginentry(picklee)      builder.putfield("mystring",       b => b.hinttag(fasttypetag.scalastring).beginentry(picklee.mystring).endentry()     )      builder.putfield("a",       b => {               b.hinttag(atypetag)         apickler.pickle(picklee.a, b)       }     )      builder.endentry()   }    override def unpickle(tag: => fasttypetag[_], reader: preader): myclass[a] = {     reader.hinttag(fasttypetag.scalastring)     val tag = reader.beginentry()     val mystringunpickled = stringunpickler.unpickle(tag, reader).asinstanceof[string]     reader.endentry()      reader.hinttag(atypetag)     val atag = reader.beginentry()     val aunpickled = aunpickler.unpickle(atag, reader).asinstanceof[a]     reader.endentry()      myclass(mystringunpickled, aunpickled)   }  } 

in addition custom pickler class, need implicit def returns pickler instance specialized concrete type arguments:

implicit def myclasspickler[a: spickler: unpickler: fasttypetag](implicit pf: pickleformat) =   new myclasspickler 

Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

rewrite - Trouble with Wordpress multiple custom querystrings -