Search code examples
scalascala-generics

Scala Generic Function... using T in Function


I'm a bit confused why the code below doesn't work:

  implicit val connectReads: Reads[ConnectCommand] = (
    (JsPath \ "uuid").read[String]
    )(ConnectCommand.apply _)

  private def generateMessage[T](json: JsValue) = json.validate[T] match {
    case s: JsSuccess[T] => s.asOpt
    case e: JsError => None
  }

The function would be called as follows:

generateMessage[ConnectCommand](json)

I'm getting the following errors:

Error:(59, 64) No Json deserializer found for type T. Try to implement an implicit Reads or Format for this type.
  private def generateMessage[T](json: JsValue) = json.validate[T] match {
                                                               ^
Error:(59, 64) not enough arguments for method validate: (implicit rds: play.api.libs.json.Reads[T])play.api.libs.json.JsResult[T].
Unspecified value parameter rds.
  private def generateMessage[T](json: JsValue) = json.validate[T] match {
                                                           ^

I'm fairly new to Scala generics... is there any way to do what I'm trying to do here?


Solution

  • According to the documentation JsValue.validate requires an implicit Reads for your type to be available:

    def validate[T](implicit rds: Reads[T]): JsResult[T] 
    

    Assuming you have it available at the place you are calling generateMessage from, you have to pass it into generateMessage, so that validate would see it as well:

    private def generateMessage[T](json: JsValue)(implicit rds: Reads[T])
    

    or the shorter form:

    private def generateMessage[T : Reads](json: JsValue)