Array-Based Codecs

Array-Based Codec derivation is enabled with this import:

sourceimport io.bullet.borer.derivation.ArrayBasedCodecs.*

Here is an example:

sourceimport io.bullet.borer.{Codec, Json}
import io.bullet.borer.derivation.key
import io.bullet.borer.derivation.ArrayBasedCodecs.*

sealed trait Animal derives Codec
case class Cat(weight: Double, color: String, home: String) extends Animal derives Codec
@key("TheDog") case class Dog(age: Int, name: String)       extends Animal derives Codec
@key(42) case class Mouse(tail: Boolean)                    extends Animal derives Codec

val cat   = Cat(8.5, "grey", "sofa")
val dog   = Dog(2, "Rex")
val mouse = Mouse(tail = true)

Json.encode(cat).toUtf8String ==> """[8.5,"grey","sofa"]"""
Json.encode(dog).toUtf8String ==> """[2,"Rex"]"""
Json.encode(mouse).toUtf8String ==> "true"

def encodeAnimal(animal: Animal) = Json.encode(animal).toUtf8String

encodeAnimal(cat) ==> """["Cat",[8.5,"grey","sofa"]]"""
encodeAnimal(dog) ==> """["TheDog",[2,"Rex"]]"""
encodeAnimal(mouse) ==> """[42,true]"""

With these codecs case classes are written to CBOR/JSON as simple arrays, unless the case class has arity 1. If the case class has only a single member, the derived codec directly writes the member without wrapping it in an array.

An Abstract Data Type (ADT) is encoded as an array of length two, with the first element holding the type ID and the second holding the instance’s encoding (i.e. an array or single element).

Check out the chapter on Type IDs for more info on type IDs and how to customized them.