Search code examples
jsonscalacirce

Modify json field type via circe


I have simple Json:

val str = """{"test":"123"}"""

How I can modify String "123" to Int 123 to get new Json?:

{"test":123}

Now I am using:

val json = parse(str).getOrElse(Json.Null)
val jsObj = json.asObject.get  // Unsafe, just example
val newJson = Json.fromJsonObject(jsObj.remove("test").add("test", Json.fromInt(123)))

But this code is not pretty.

Is it possible to make this code prettier or maybe do it via circe optics?


Solution

  • It should do the trick depending on how you want to manage the limit case (here I throw an exception):

    import io.circe._
    import io.circe.parser.parse
    
    val str = """{"test":"123"}"""
    val json = parse(str).getOrElse(Json.Null)
    json.mapObject(
      _.mapValues( v =>
        v.asString
         .flatMap(parse(_).toOption)
         .getOrElse(throw new IllegalArgumentException("No String found"))
      )
    )