I started with the accepted answer to SO question 53573659 which has a nested list of attrs and uses the auto-parser to get the data into case classes. I want to be able to handle the same data but with the nested fields having kebab-case rather than camel case.
Here is the same input JSON with the kebab-case fields
val sampleKebab="""{
"parent" : {
"name" : "title",
"items" : [
{
"foo" : "foo1",
"attrs" : {
"attr-a" : "attrA1",
"attr-b" : "attrB1"
}
},
{
"foo" : "foo2",
"attrs" : {
"attr-a" : "attrA2",
"attr-b" : "attrB2",
"attr-c" : "attrC2"
}
}
]
}
}"""
I can decode the attrs data by itself using the following example
import io.circe.derivation.deriveDecoder
import io.circe.{Decoder, derivation}
import io.circe.generic.auto._
import io.circe.parser._
val attrKebabExample = """{
"attr-a": "attrA2",
"attr-b": "attrB2",
"attr-c": "attrC2"
}"""
case class AttrsKebab(attrA: String, attrB: String)
implicit val decoder: Decoder[AttrsKebab] = deriveDecoder(derivation.renaming.kebabCase)
val attrKebabData = decode[AttrsKebab](attrKebabExample)
attrKebabData decodes to
Either[io.circe.Error,AttrsKebab] = Right(AttrsKebab(attrA2,attrB2))
When I try to tie this decoder into the case class hierarchy from the original question, it exposes some glue that I am missing to hold it all together
case class ItemKebab(foo: String, attrs : AttrsKebab)
case class ParentKebab(name: String, items: List[ItemKebab])
case class DataKebab(parent : ParentKebab)
case class Data(parent : Parent)
val dataKebab=decode[DataKebab](sample)
In this case, dataKebab contains a DecodingFailure
Either[io.circe.Error,DataKebab] = Left(DecodingFailure(Attempt to decode value on failed cursor, List(DownField(attr-a), DownField(attrs), DownArray, DownField(items), DownField(parent))))
My guess is that either the decoder I defined is being ignored, or I need to explicitly define more of the decode process, but I'm looking for some help to find what the solution might be.