当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《Scodec组合器:标头包含用于区分类型的幻数》经验,为你挑选了1个好方法。

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

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.注意,有一些字段将鉴别器与鉴别值分开.

我见过一个带字节排序的例子.但据我所知,这种"鱿鱼"编码鉴别器不会往返.解决这个问题的正确方法是什么?



1> 小智..:

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

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]
} 

推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有