I am new to Scala and I need to figure out how to process a JSON depending on two scenarios.
First is where I receive such a JSON:
{..."field":[{"count":1,"value":"foo"}]...}
Second scenario is where I receive this kind of JSON: {..."field":"foo"...}
I can not determine when each JSON will come in(it is random). In both scenarios I need to get the field
value and store as a String into separate JSON. Second scenario is obvious as it is a String already but I can not figure out how to determine whenever this field is Array or String and if Array then get the "foo"
from JSON within it. I know how to access the field
as it is a cursor:
val field = cursor.downField("foo").downField("bar").downField("lorem").downField("field")
Below example of my approach which is not working:
if (field.asInstanceOf[String]) {
rowFiltered.set("field", field.as[String])
} else {
rowFiltered.set("field", field.as[Seq[field[0]]])
}
Help with determining and assigning will be appreciated.
CodePudding user response:
You can use orElse
and pass another parsing.
import io.circe._
import io.circe.literal.JsonStringContext
object App {
final case class MyField(value: String)
def main(args: Array[String]): Unit = {
val jsonValue01: Json =
json"""{
"hello": "world",
"field":[{"count":1,"value":"foo01"}],
"foo" : "bar"
}"""
val jsonValue02: Json =
json"""{
"hello": "world",
"field": "foo02",
"foo" : "bar"
}"""
implicit val decodeField: Decoder[MyField] = new Decoder[MyField] {
final def apply(c: HCursor): Decoder.Result[MyField] =
for {
foo <- c.downField("field").downN(0).downField("value").as[String]
.orElse(c.downField("field").as[String])
} yield {
new MyField(foo)
}
}
val myField01 = jsonValue01.as[MyField]
val myField02 = jsonValue02.as[MyField]
println(myField01) //Right(MyField(value = foo01))
println(myField02) //Right(MyField(value = foo02))
}
}