I have a json that looks somewhat like this:
{
"results": {
"result_1": {
"text": "abc"
},
"result_2": {
"text": "def"
}
}
}
I wish to decode it to a case class that looks like:
case class Results(results: List[SingleResult])
case class SingleResult(text: String)
I wish to write a decoder for this but my current decoder isn't compiling. It looks like this:
implicit val singleResultDecoder: Decoder[SingleResult] = deriveDecoder[SingleResult]
implicit val ResultsDecoder: Decoder[Results] = new Decoder[Results] {
override def apply(c: HCursor): Result[Results] = {
for {
results <- c.keys.map(_.map(k => c.downField(k).as[SingleResult]).toList)
} yield Results(results = results)
}
}
The compilation error is:
Type mismatch :
Required: scala.List[SingleResult]
Found: scala.List[Result[SingleResult]]
Any directions on how to fix the error would be appreciated.
You are mixing few things here. In your json, you don't have a list, as you are trying to read it. You have a map. Therefore we need to have our Decoder
accordingly:
implicit val ResultsDecoder: Decoder[Results] = new Decoder[Results] {
override def apply(c: HCursor): Result[Results] = {
for {
results <- c.downField("results").as[Map[String, SingleResult]]
} yield Results(results = results.values.toList)
}
}
Then calling:
val decodedFoo = circe.jawn.decode[Results](jsonString)
println(decodedFoo)
results in:
Right(Results(List(SingleResult(abc), SingleResult(def))))
Code run in Scastie.