3

Circleを使用して作業しようとしているユースケースは次のとおりです。JSON メッセージのストリームが与えられた場合、op で照合し、メッセージを適切な型との間で変換します。以下のコードは、すべての詳細を示しています。ただし、さまざまな ResponseMessag:es に対して暗黙的なエンコーダーが必要なため、コードはコンパイルされません。

import io.circe.generic.auto._さまざまなタイプのエンコーダーとデコーダーを取得してからカスタムResponseMessageを作成するだけでは十分ではないのはなぜResponseMessageですか? 以下の例を変更して、テストに合格するにはどうすればよいですか? ResponseOpType のさまざまな値を文字列としてデコードする必要がない方法はありtraitますか?階層が必要ですが、間違った形式でデコードされます (プレーンな文字列ではなく JSON オブジェクトとして)?

object OpTypes {
  type ResponseOpType = String
  val Connection: ResponseOpType = "connection"
  val Status: ResponseOpType = "status"
}
import OpTypes._

sealed trait ResponseMessage {
  /* The operation type */
  def op: ResponseOpType
  /* Client generated unique id to link request with response (like json rpc) */
  def id: Integer
}

case class ConnectionMessage (
                               op: ResponseOpType,
                               id: Integer,
                               /* The connection id */
                               connectionId: String
                             ) extends ResponseMessage

case class StatusMessage (
                           op: ResponseOpType,
                           id: Integer,
                           /* Additional message in case of a failure */
                           errorMessage: String,
                           /* The type of error in case of a failure */
                           errorCode: String,
                           /* The connection id */
                           connectionId: String,
                           /* Is the connection now closed */
                           connectionClosed: Boolean,
                           /* The status of the last request */
                           statusCode: String
                         ) extends ResponseMessage

case class UnableToParseStreamResponseMessage (op:String="Error", id:Integer = 0) extends ResponseMessage

  test("Circle support") {
    import io.circe.{Decoder, Encoder}
    import io.circe.generic.auto._
    import io.circe.syntax._
    import io.circe.parser.decode

    implicit val decodeResponseMessage: Decoder[ResponseMessage] = Decoder.instance(c => {
      c.get[OpTypes.ResponseOpType]("op").flatMap {
        case OpTypes.Connection => c.as[ConnectionMessage]
        case OpTypes.Status => c.as[StatusMessage]
        case _ => c.as[UnableToParseStreamResponseMessage]
      }
    })

    implicit val encodeResponseMessage: Encoder[ResponseMessage] = new Encoder[ResponseMessage] {
      final def apply(a: ResponseMessage): Json = Json.obj(
        //Im encoding ResponseMessage wich only have a subset of all the parameters I need???
      )
    }

    val originalJson =
      """
        |{"op":"connection",
        | "id":1,
        | "connectionId":"1"
        | }
      """.stripMargin
    val original = ConnectionMessage(op ="connection", id = 1, connectionId = "1")

    decode[ResponseMessage](originalJson) shouldBe original
    originalJson shouldBe original.asJson.noSpaces
  }
4

0 に答える 0