Ian Juma
Ian Juma

Reputation: 107

custom spray-json marshaller for a case class with Value type

case class HydraQueueMessage(tableType: HydraTableName.Value, payload: String)


object MedusaElementFormat extends DefaultJsonProtocol {
  implicit object HydraElementFormat extends RootJsonFormat[HydraQueueMessage] {
    def write(message: HydraQueueMessage) = JsObject(
      MedusaEnum.HydraTableName.toString -> JsString(message.tableType.toString),
      "payload" ->  JsString(message.payload)
    )
    def read(value: JsValue) = {
      value.asJsObject.getFields("tableType", "payload") match {
        case Seq(JsString(tableType), JsString(payload)) =>
          new HydraQueueMessage(tableType = tableType, payload = payload)
      }
    }
  }
}

There's a type miss-match in this example, is there a cleaner way to achieve this? And still having the tableType as a Value and not String?

My marshaller throws a type miss-match with the Value type, I can't marshall JsValue either. So how would I proceed to marshall the HydraQueueMessage case class without using a String type for tableType?

Upvotes: 1

Views: 1021

Answers (1)

Carlos Vilchez
Carlos Vilchez

Reputation: 2804

You are trying to process too much at once. I would divide your problem in 2:

  1. Process HydraTableName.Value
  2. Process HydraQueueMessage

That will make things much easier.

To process your enum:

implicit object StepFormatJsonFormat extends RootJsonFormat[HydraTableName.Value] {
  def write(obj: HydraTableName.Value): JsValue = JsString(obj.toString)

  def read(jsonValue: JsValue): HydraTableName.Value = jsonValue match {
    case JsString(stringObj) => HydraTableName.withName(stringObj)
    case otherValue => throw new DeserializationException(s"HydraTableName.Value not found in ${otherValue.toString}")
  }
}

Then the typical case class formatting:

implicit val HydraQueueMessageFormat = jsonFormat2(HydraQueueMessage.apply)

Probably the way to process the enum should be adapted. If you include the HydraTableName, I can update the code.

Upvotes: 3

Related Questions