0

I'm using Rapture JSON with Argonaut backend (can change that if necessary).

Given an arbitrary JSON string, I need to parse it as a flat object (no nested JSON objects) to ideally obtain a list of tuples (fieldName, fieldType, fieldValue) for each field.

import rapture.json._
import rapture.json.jsonBackends.argonaut._

val j = json"""{"what":"stuff"}"""
val extracted: List[(String, FieldType, Any)] = j.someMagic()

// So I can do this
extracted.map { _ match {
  case (k, JString, v) => println("I found a string!")
  ...
}}

UPDATE: this became a github issue in rapture-json

sscarduzio
  • 5,938
  • 5
  • 42
  • 54

1 Answers1

3

I kinda worked around this one using Argonaut directly. Been a bit brutal with all those options and scalaz disjunctions, enhancements are welcome!

import rapture.json._
import rapture.json.jsonBackends.argonaut._

val parsed: Disjunction[String, argonaut.Json] = argonaut.Parse.parse(
  """{"what":"stuff", "num": 1, "bool":true}""")


val fieldzAndValues: Disjunction[String, Option[List[(argonaut.Json.JsonField, argonaut.Json)]]] = for {
  jo <- parsed
  flds = jo.hcursor.fields
  vls = jo.objectValues
} yield vls.map( v => flds.map(_.zip(v))).flatten

fieldzAndValues.toOption.flatten.map(_.map(_ match {
  case (k, v) if(v.isString) => s"$k string $v" 
  case (k, v) if(v.isBool) => s" $k bool $v" 
  case (k, v) if(v.isNull) => s"$k null $v" 
  case (k, v) if(v.isNumber) => s" $k number $v" 
}))
// res0: Option[List[String]] = Some(List(what string "stuff",  num number 1,  bool bool true))
sscarduzio
  • 5,938
  • 5
  • 42
  • 54