我正在寻找一种方法来处理如下例子的协议:
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
.注意,有一些字段将鉴别器与鉴别值分开.
我见过一个带字节排序的例子.但据我所知,这种"鱿鱼"编码鉴别器不会往返.解决这个问题的正确方法是什么?
有几种方法可以做到,但这是我用过的方法:
import scodec._ import scodec.codecs._ import scodec.bits._ case class Request(bodyType: Int, foo: Int, bar: 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] }