2016-03-07 13 views
1
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) 
     } 
    } 
    } 
} 

В этом примере есть пропуская встреча типа, есть ли более чистый способ достичь этого? И все еще имея tableType как значение, а не строку?пользовательский распылитель-json маршаллер для класса корпуса с типом значения

Мой маршаллер выбрасывает совпадение типа с типом значения, я также не могу настроить JsValue. Итак, как мне перейти на маршал класса HydraQueueMessage без использования строкового типа для tableType?

ответ

3

Вы пытаетесь обработать слишком много сразу. Я бы разделил вашу проблему в 2:

  1. Процесс HydraTableName.Value
  2. Процесс HydraQueueMessage

Это сделает вещи намного проще.

Для обработки вашего перечисления:

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}") 
    } 
} 

Тогда типичный случай форматирования класса:

implicit val HydraQueueMessageFormat = jsonFormat2(HydraQueueMessage.apply) 

Вероятно, способ обработки перечисления должен быть адаптирован. Если вы включили HydraTableName, я могу обновить код.