我正在尝试定义用于与EELink GPS通信的Scodec副产品编解码器。
以下是代码:
import scodec.Codec
import scodec.bits.ByteVector
import scodec.codecs._
trait Message
object Message {
implicit val discriminated: Discriminated[ Message, Int ] = Discriminated(uint8)
val codec: Codec[ Message ] = Codec.coproduct[ Message ].discriminatedByIndex(uint8)
}
case class GpsId(value: ByteVector)
object GpsId {
val codec = bytes(8).as[ GpsId ]
}
case class SerialNumber(value: Int)
object SerialNumber {
val codec = uint16.as[ SerialNumber ]
}
case class Header(protocolNumber: Int, length: Int, serial: SerialNumber)
object Header {
val codec = (uint8 :: uint16 :: SerialNumber.codec).as[ Header ]
}
case class Login(header: Header, id: GpsId, language: Int) extends Message
object Login {
val protocolNumber = 0x01
implicit val discriminator: Discriminator[ Message, Login, Int ] = Discriminator(protocolNumber)
implicit val codec: Codec[Login] = (Header.codec :: GpsId.codec :: uint8).as[ Login ]
}
我得到以下内容:
Error:(14, 48) could not find implicit value for parameter auto: scodec.codecs.CoproductBuilderAuto[com.tecnoguru.ridespark.gps.eelink.messages.Message]
val codec: Codec[ Message ] = Codec.coproduct[ Message ].discriminatedByIndex(uint8)
^
我看过Scodec - Coproducts could not find implicit value for parameter auto: scodec.codecs.CoproductBuilderAuto但是没有帮助,从我看到我正确定义编解码器和鉴别器。
我使用scodec-core 1.7.0和scodec-bits 1.0.5在Scala 2.11.5上运行
答案 0 :(得分:3)
现在的代码需要进行两处小改动:
Message
特征必须为sealed
,否则,Shapeless将不会提供Generic.Aux[Message, SomeCoproduct]
个实例。Codec.coproduct[Message]
的调用必须在定义所有子类型之后。将伴侣移动到文件末尾就足够了。通过这两个更改,示例成功编译。