I have the following JSON structure:
{
"e":[],
"r":{
"foo":[
[
"abc",
1
],
[
"def",
2
],
]
}
}
I am trying to decode this structure and have set up the following case class:
case class Baz(e : List[String], r : List[Data])
where Data is
case class Data(a : String, b : Int)
So I setup my circe decoder as follows:
object Data{
implicit val decoder : Decoder[Data] (c : HCursor) =>
for {
a <- c.downN(0).as[String]
b <- c.downN(1).as[Int]
}yield(Data(a,b))
}
The obvious implementation for the Baz decoder is
object Baz{
implicit val decoder : Decoder[Baz] (c : HCursor) =>
for {
e <- c.downField("e").as[List[String]]
r <- c.downField("r").downField("foo").as[List[Data]]
}yield(Baz(e,r))
}
However, I would like to use the same Baz decoder for other JSON values which only differ in the key name "foo". That is, "foo" could be something else like "bar".
How do I tell/move the cursor so that it works irrespective of the value of the key for the List[Data]?
Using a Map
encoding will allow you to re-use the decoder and slurp any JSON value of the same structure:
object Baz{
implicit val decoder : Decoder[Baz] (c : HCursor) =>
for {
e <- c.downField("e").as[List[String]]
r <- c.downField("r").as[Map[String, List[Data]]]
}yield(Baz(e,r))
}