0

I have class as below

trait RiskCheckStatusCode {
  def code: String
  def isSuccess: Boolean
}

object RiskCheckStatusCode {

  val SUCCESS = SuccessRiskCheckStatusCode("1.1.1")
  val FAIL = FailRiskCheckStatusCode("2.2.2")

  case class SuccessRiskCheckStatusCode(code: String) extends RiskCheckStatusCode {
    override def isSuccess = true
  }

  object SuccessRiskCheckStatusCode {
    import spray.json.DefaultJsonProtocol._
    implicit val formatter = jsonFormat1(SuccessRiskCheckStatusCode.apply)
  }

  case class FailRiskCheckStatusCode(code: String) extends RiskCheckStatusCode {
    override def isSuccess = false
  }

  object FailRiskCheckStatusCode {
    import spray.json.DefaultJsonProtocol._
    implicit val formatter = jsonFormat1(FailRiskCheckStatusCode.apply)
  }
}

and now I would like to convert the list of RiskCheckStatusCode to json

object Main extends App{

import spray.json._
import spray.json.DefaultJsonProtocol._

  val l = List(RiskCheckStatusCode.SUCCESS, RiskCheckStatusCode.FAIL)

  implicit object RiskCheckStatusCodeJsonFormat extends JsonWriter[RiskCheckStatusCode] {
    override def write(obj: RiskCheckStatusCode): JsValue = obj match {
      case obj: SuccessRiskCheckStatusCode => obj.toJson
      case obj: FailRiskCheckStatusCode => obj.toJson
    }
  }

  def json[T](list: T)(implicit formatter: JsonWriter[T]) = {
    print(list.toJson)
  }

  json(l)
}

but the json method can not find jsonWriter[RiskCheckStatusCode]. Can you explain why? Maybe should I do it differently for trait type?

Edit: It works for

 val l: RiskCheckStatusCode = RiskCheckStatusCode.SUCCESS

so the problem is with List[RiskCheckStatusCode] because I have a formatter for RiskCheckStatusCode, not for List[RiskCheckStatusCode]. I tried import DefaultJsonProtocol but it still does not work.

import spray.json.DefaultJsonProtocol._

I have to change the definitions? From

implicit object RiskCheckStatusCodeJsonFormat extends JsonWriter[RiskCheckStatusCode]

to

implicit object RiskCheckStatusCodeJsonFormat extends JsonWriter[List[RiskCheckStatusCode]]

error:

Error:(28, 7) Cannot find JsonWriter or JsonFormat type class for List[com.example.status.RiskCheckStatusCode]
  json(l)

Error:(28, 7) not enough arguments for method json: (implicit formatter: spray.json.JsonWriter[List[com.example.status.RiskCheckStatusCode]])Unit.
Unspecified value parameter formatter.
  json(l)
mForest
  • 88
  • 11

1 Answers1

0

Your code is fine you are just not having toJson in your scope (it is located in the package object of spray.json).

Add it and your code should compile:

object Main extends App with DefaultJsonProtocol {

  import spray.json._

  // ...

}

Furthermore spray has some issues to lift JsonWriter through derived formats (see this for details).

You can switch to JsonFormat instead:

implicit object RiskCheckStatusCodeJsonFormat extends JsonFormat[RiskCheckStatusCode] {
  override def write(obj: RiskCheckStatusCode): JsValue = obj match {
    case obj: SuccessRiskCheckStatusCode => obj.toJson
    case obj: FailRiskCheckStatusCode => obj.toJson
  }

  override def read(json: JsValue): RiskCheckStatusCode = ???
}

In addition, to cleanup the type of your List change the definition of RiskCheckStatusCode to (this explains more details):

sealed trait RiskCheckStatusCode extends Serializable with Product
Sebastian
  • 16,813
  • 4
  • 49
  • 56