How to write scodec codec for Collection Map

262 Views Asked by At

I have below case class

case class Foo(code: Int, msg: String, headers: Map[String,String] = Map.empty)

Below is the code that I've tried so far -

import scodec._
import scodec.codecs._

implicit val mapCodec: Codec[List[(String, String)]] = sizedList()

implicit val fooCodec : Codec[Foo] = {
    ("code" | int32) :: ("msg" | cstring) :: ("headers" | mapCodec)
}.as[Foo]

I don't know how to write Codec for Map[String, String]. I checked online documentation but it is still in TODO.

Any idea how can I write the codec for Map[String, String]?

1

There are 1 best solutions below

0
Ivan Kurchenko On BEST ANSWER

What you would need to do is to define Codec for tuple of strings, which then you will need to use to create codec for List[(String, String)] which can be converted to Map[String, String] and vice versa, hence covert Codec using xmap function.

So the final solution might look like:

import scodec._
import scodec.codecs._
case class Foo(code: Int, msg: String, headers: Map[String,String] = Map.empty)

implicit val tupleCodec : Codec[(String, String)] = cstring.pairedWith(cstring)
implicit val mapCodec: Codec[Map[String, String]] = list(tupleCodec).xmap(_.toMap, _.toList)

implicit val fooCodec : Codec[Foo] = {
  ("code" | int32) :: ("msg" | cstring) :: ("headers" | mapCodec)
}.as[Foo]

Hope this helps!