Nigel Eke - Personal Site

Scodec Discriminator example

I am using the scodec library as part of an application I am writing. Part of the implementation requires encoding / decoding case classes that are derived from a specific trait.

This example enabled me to achieve that task:

package scodec.helloworld

import scodec._
import scodec.codecs._
import scodec.codecs.implicits._

import scala.language.implicitConversions

trait Parent
case class Child1(value: Int) extends Parent
case class Child2(value: String) extends Parent

object ChildType extends Enumeration {
  type ChildType = Value
  val ONE, TWO = Value

object Child1 {
  implicit val codec : Codec[Child1] = {
    ("value" | uint16).hlist

object Child2 {
  implicit val codec : Codec[Child2] = {
    ("value" | ascii).hlist

object Parent {
  import ChildType._
  implicit val childTypeCodec : Codec[ChildType] = enumerated(uint8, ChildType)

  implicit val codec : Codec[Parent] = discriminated[Parent].by(Codec[ChildType])
      .typecase(ChildType.ONE, Codec[Child1])
      .typecase(ChildType.TWO, Codec[Child2])

object Discrimating {

  def main(args: Array[String]) = {

    val child1 : Parent = Child1(1)
    roundTrip("Child1", child1)

    val child2 : Parent = Child2("Two")
    roundTrip("Child2", child2)

    val children = List[Parent](child1, child2)
    roundTrip("Children", children)

  def roundTrip[T](what: String, value: T)(implicit codec: Codec[T]) = {
    println(s"$what: $value")

    val encodedValue = Codec.encode(value).require
    println(s"Encoded $what: $encodedValue")

    val decodedValue = Codec.decode[T](encodedValue).require.value
    println(s"Decoded $what: $decodedValue")

    assert(value == decodedValue)


The output of the program is:

Child1: Child1(1)
Encoded Child1: BitVector(24 bits, 0x000001)
Decoded Child1: Child1(1)
Child2: Child2(Two)
Encoded Child2: BitVector(32 bits, 0x0154776f)
Decoded Child2: Child2(Two)
Children: List(Child1(1), Child2(Two))
Encoded Children: BitVector(88 bits, 0x000000020000010154776f)
Decoded Children: List(Child1(1), Child2(Two))

Posted: March 11, 2018