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
Post a Comment