Search code examples
scalascodec

How to write scodec codec for Collection Map


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]?


Solution

  • 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!