scala – Scodec组合器:标头包含用于区分类型的幻数

我正在寻找一种方法来处理如下例子的协议:

case class Request(bodyType: Int,foo: Int,bar: Int,body: RequestBody)

sealed trait RequestBody
case class Read(key: String) extends RequestBody
case class Write(key: String,value: Array[Byte]) extends RequestBody

这里,bodyType == 0代表Read,bodyType!= 0代表Write.
注意,有一些字段将鉴别器与鉴别值分开.

我见过an example with byte-ordering.
但据我所知,这种“鱿鱼”编码鉴别器不会往返.
解决这个问题的正确方法是什么?

解决方法

有几种方法可以做到,但这是我用过的方法

import scodec._
import scodec.codecs._
import scodec.bits._

case class Request(bodyType: Int,body: RequestBody)

sealed trait RequestBody
case class Read(key: String) extends RequestBody
object Read {
  implicit val codec: Codec[Read] = ("key" | utf8).as[Read]
  implicit val discriminator: discriminator[RequestBody,Read,Int] = discriminator(0)
}
case class Write(key: String,value: ByteVector) extends RequestBody
object Write {
  implicit val codec: Codec[Write] = {
    ("key"   | utf8  ) ::
    ("value" | bytes )
  }.as[Write]
  implicit val discriminator: discriminator[RequestBody,Write,Int] = discriminator(1)
}

object Request {
  implicit val codec: Codec[Request] = {
    ("bodyType" | uint16 ).flatPrepend { bodyType =>
    ("foo"      | uint16 ) ::
    ("bar"      | uint16 ) ::
    ("body"     | Codec.coproduct[RequestBody].discriminatedBy(provide(bodyType)).auto)
  }}.as[Request]
}

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...