jsoniter-scala icon indicating copy to clipboard operation
jsoniter-scala copied to clipboard

Can i get type of object in json like a string ?

Open 2MD opened this issue 4 years ago • 1 comments

Hello! I have a json: {"id":"09", "name": "Nitin", "department":"Finance", "help": ["a", "b"], "mm" : {"22": "11"}, "z": 12 } and I need to get some case class A(name: String, value: String, type: String)

A("id","09","string") A("name","Nitin","string") A("department","Finance","string") A("help","["a", "b"]","array") A("mm","{"22": "11"}", "map") A("z": 12, "integer")

How i can do it?

2MD avatar Nov 26 '21 07:11 2MD

Hi, @2MD! Please check if the following solution suits your needs:

import com.github.plokhotnyuk.jsoniter_scala.macros._
import com.github.plokhotnyuk.jsoniter_scala.core._
import java.nio.charset.StandardCharsets._

object Example01 {
  case class A(name: String, value: String, `type`: String)

  implicit val codec: JsonValueCodec[List[A]] = new JsonValueCodec[List[A]] {
    override def decodeValue(in: JsonReader, default: List[A]): List[A] = {
      if (in.isNextToken('{')) {
        if (!in.isNextToken('}')) {
          in.rollbackToken()
          val as = List.newBuilder[A]
          while ({
            val name = in.readKeyAsString()
            val token = in.nextToken()
            in.rollbackToken()
            var value = "null"
            val `type` =
              if (token == '"') {
                value = in.readString(null)
                "string"
              } else {
                value = new String(in.readRawValAsBytes(), UTF_8)
                if (token == 'f' || token == 't') "boolean"
                else if ((token >= '0' && token <= '9') || token == '-') {
                  if ((value.indexOf('.') & value.indexOf('e') & value.indexOf('E')) < 0) "double"
                  else "integer"
                } else if (token == '[') "array"
                else if (token == '{') "map"
                else if (token == 'n') "null"
                else in.decodeError("expected JSON value")
              }
            as += A(name, value, `type`)
            in.isNextToken(',')
          }) ()
          if (!in.isCurrentToken('}')) in.objectEndOrCommaError()
          as.result()
        } else nullValue
      } else nullValue
    }

    override def encodeValue(x: List[A], out: JsonWriter): Unit = {
      out.writeObjectStart()
      x.foreach { a =>
        out.writeKey(a.name)
        if (a.`type` == "string") out.writeVal(a.value)
        else out.writeRawVal(a.value.getBytes(UTF_8))
      }
      out.writeObjectEnd()
    }

    override val nullValue: List[A] = Nil
  }

  def main(args: Array[String]): Unit = {
    val as: List[A] =
      readFromString("""{"id":"09", "name": "Nitin", "department":"Finance", "help": ["a", "b"], "mm" : {"22": "11"}, "z": 12 }""")
    println(as)
    println(writeToString(as))
  }
}

An expected output:

List(A(id,09,string), A(name,Nitin,string), A(department,Finance,string), A(help,["a", "b"],array), A(mm,{"22": "11"},map), A(z,12,double))
{"id":"09","name":"Nitin","department":"Finance","help":["a", "b"],"mm":{"22": "11"},"z":12}

plokhotnyuk avatar Nov 26 '21 09:11 plokhotnyuk