How to use specific apply method in implicit Json `reads` from Scala -


i have class takes few optional enumeration types in constructor:

case class gpmedia(id: option[gpid], created: option[datetime], active: option[boolean], data: array[byte], mimetype: option[gpmediatype.type], encoding: option[gpencoder.codec], compression: option[gpcompressor.type]) 

i've been struggling create implicit json reads method works. keep ending errors such as:

[error] /users/zbeckman/projects/glimpulse/server/project/glimpulse-server/app/utility/gpmedia.scala:57: overloaded method value apply alternatives: etc... 

what i'm trying translate inbound json strings, turning them right kind of option instance (eg., mime type "image/png" in json turn option(gpmediatype(v)). gpmediatype constructor map string, , return correct value (one of gpmediatype.unknown).

here's implicit reads i've worked far, implemented on gpmedia class' companion object...

case object gpmedia extends gprequestlogging {     implicit val reads: reads[gpmedia] = (         (__ \ "id").readnullable[gpid] ,             (__ \ "created").readnullable[datetime] ,             (__ \ "active").readnullable[boolean] ,             (__ \ "data").read[array[byte]] ,             (__ \ "mimetype").readnullable[string].map(v => option(gpmediatype(v))) ,             (__ \ "encoding").readnullable[string].map(v => option(gpencoder(v.get))) ,             (__ \ "compression").readnullable[string].map(v => option(gpcompressor(v.get)))         )(gpmedia.apply _) } 

this works, when try add other apply() methods, goes heck. how can apply specific apply method in json reads implementation? example, when add apply method:

def apply(data: array[byte]) = new gpmedia(none, none, none, data, none, none, none) 

i end with:

[error] /users/zbeckman/projects/glimpulse/server/project/glimpulse-server/app/utility/gpmedia.scala:60: ambiguous reference overloaded definition, [error] both method apply in object gpmedia of type (id: option[models.gpid], created: option[org.joda.time.datetime], active: option[boolean], data: array[byte], mimetype: option[utility.gpmediatype.type], encoding: option[utility.gpencoder.codec], compression: option[utility.gpcompressor.type])utility.gpmedia [error] ,  method apply in object gpmedia of type (data: array[byte])utility.gpmedia [error] match expected type ? [error]         )(gpmedia.apply _) 

i've tried few different approaches, such (gpmedia.apply(...)) can't seem parameters right.

i'm new whole json implicit reader/writer , json decoding syntax. i'm missing here...

edit

here's example, regarding attempt call specific apply method:

implicit val reads: reads[gpmedia] = (     (__ \ "id").readnullable[gpid] ,         (__ \ "created").readnullable[datetime] ,         (__ \ "active").readnullable[boolean] ,         (__ \ "data").read[array[byte]] ,         (__ \ "mimetype").readnullable[string].map(v => option(gpmediatype(v))) ,         (__ \ "encoding").readnullable[string].map(v => option(gpencoder(v.get))) ,         (__ \ "compression").readnullable[string].map(v => option(gpcompressor(v.get)))     )(v => gpmedia.apply(v.id, v.created, v.active, v.data, v.mimetype, v.encoding, v.compression)) 

this results in:

[error] /users/zbeckman/projects/glimpulse/server/project/glimpulse-server/app/utility/gpmedia.scala:60: type mismatch; [error]  found   : utility.gpmedia [error]  required: (option[models.gpid], option[org.joda.time.datetime], option[boolean], array[byte], option[utility.gpmediatype.value], option[utility.gpencoder.value], option[utility.gpcompressor.type]) [error]     (which expands to)  (option[models.gpid], option[org.joda.time.datetime], option[boolean], array[byte], option[utility.gpmediatype.value], option[utility.gpencoder.value], option[utility.gpcompressor.value]) [error]         )(v => gpmedia.apply(v.id, v.created, v.active, v.data, v.mimetype, v.encoding, v.compression)) [error]                             ^ 

this not possible. compiler not know apply method use. 1 of caveats of using overloaded methods. way can make "nice" rename methods, or alias overloaded apply methods different names , use those.


your second attempt not work because compiler expecting function signature similar apply, like:

(option[gpid], option[datetime], option[boolean], array[byte], option[string], option[string], option[string]) => gpmedia 

but you're trying use:

gpmedia => gpmedia 

which doesn't work, because don't yet have gpmedia object, tupled fields. more like:

implicit val reads: reads[gpmedia] = (     (__ \ "id").readnullable[gpid] ,     (__ \ "created").readnullable[datetime] ,     (__ \ "active").readnullable[boolean] ,     (__ \ "data").read[array[byte]] ,     (__ \ "mimetype").readnullable[string].map(v => option(gpmediatype(v))) ,     (__ \ "encoding").readnullable[string].map(v => option(gpencoder(v.get))) ,     (__ \ "compression").readnullable[string].map(v => option(gpcompressor(v.get))) ).tupled.map(v => gpmedia.apply(v._1, v._2, v._3, v._4, v._5, v._6, v._7)) 

which not good. can make better this:

implicit val reads: reads[gpmedia] = (     (__ \ "id").readnullable[gpid] ,     (__ \ "created").readnullable[datetime] ,     (__ \ "active").readnullable[boolean] ,     (__ \ "data").read[array[byte]] ,     (__ \ "mimetype").readnullable[string].map(v => option(gpmediatype(v))) ,     (__ \ "encoding").readnullable[string].map(v => option(gpencoder(v.get))) ,     (__ \ "compression").readnullable[string].map(v => option(gpcompressor(v.get))) ).tupled.map(v => gpmedia.apply _ tupled v) 

except end same problem started with, because compiler not able choose correct apply method. have no choice rename or make things ugly.


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -