borer-compat-cats
The borer-compat-cats
module provides default codecs for the following cats.data._
data structures from the cats cats-core
package:
Chain[A]
Ior[A, B]
NonEmptyChain[T]
NonEmptyList[T]
NonEmptyMap[T]
NonEmptySet[T]
NonEmptyVector[T]
Validated[A, B]
Installation
Include the borer-compat-cats
module as a dependency (see the Getting Started chapter for details) and
import io.bullet.borer.compat.cats.*
With this import in place borer will seamlessly encode and decode instances of the types listed above, provided that encoders and/or decoders are available for the respective “inner” types.
Encoding Strategies
While the encoding strategies for most of the above data structures should be relatively straight-forward there are two types, for which there is no clear default encoding:
Ior[A, B]
Validated[A, B]
The encodings implemented by borer-compat-circe
aim for best time and space efficiency, not “readability”.
One easy way to optimize for self-describability rather than efficiency would be to rely on borer-derivation
instead. Here is an example contrasting the difference:
sourceimport cats.data.Ior
import io.bullet.borer.{Decoder, Encoder, Codec, Json}
val value = List(
Ior.Left(1),
Ior.Right("foo"),
Ior.Both(42, "bar")
)
// the Ior encoding of `borer-compat-circe` is optimized for efficiency
{
import io.bullet.borer.compat.cats.*
Json.encode(value).toUtf8String ==>
"""[[0,1],[1,"foo"],[2,42,"bar"]]"""
}
// the map-based codec generated by `borer-derivation` produces encodings
// that self-describe better, but are less efficient space and time-wise
{
given [A: Encoder: Decoder, B: Encoder: Decoder]: Codec[Ior[A, B]] =
MapBasedCodecs.deriveAllCodecs[Ior[A, B]]
Json.encode(value).toUtf8String ==>
"""[{"Left":{"a":1}},{"Right":{"b":"foo"}},{"Both":{"a":42,"b":"bar"}}]"""
}
See the module sources for full details.