I have a claas that jsoniter is able to create automatically a custom codec, except for the key of a map.
How to create a custom codec just for the key?
case class IconReference(area: AreaId, source: IconSource, id: String)
sealed trait TreeStatisticOperation:
id: String
case class ApiTreeNode(
value: String,
label: String,
field: String,
path: List[Int],
icon: Option[IconReference],
statistics: Map[TreeStatisticOperation, Option[Double]],
)
In this example, I need only to customize how TreeStatisticOperation
is handled, and avoid writing a codec that handles all the details.
You need to define an implicit JsonKeyCodec
:
given JsonKeyCodec[String] with {
def decodeKey(in: JsonReader): String = in.readKeyAsString()
def encodeKey(x: String, out: JsonWriter): Unit = out.writeKey(x)
}
Unfortunately, there is no macro for it, nor any .map
/.contramap
, so you'd have to use methods in JsonReader
and JsonWriter
to get one of primitives (String, Boolean, numeric type) and convert to/from it manually.
In your case that would be:
given JsonKeyCodec[TreeStatisticOperation] with {
def decodeKey(in: JsonReader): TreeStatisticOperation =
// assuming withName(name: String): TreeStatisticOperation
TreeStatisticOperation.withName(in.readKeyAsString())
def encodeKey(x: TreeStatisticOperation, out: JsonWriter): Unit =
out.writeKey(x.id)
}