1

I have an Api that I need to do multiple concurrent call with cursor, but I'm interested in only knowing the size of an array in the Json only, I wonder if is it possible to make a custom decoder with Circe or Jsoniter for it? The Json look simple only like this:

{
   "myArray":[
      {
         "multipleJsonObjectsHere"
      }
   ],
   "cursor":"abc"
}

I just want to retrieve only the size of myArray to know how many items are there in it

iron_bat
  • 21
  • 2

1 Answers1

0

Using jsoniter-scala you can write a custom codec that will parse/serialize JSON array to/from Int value:

case class Message(myArray: Int, cursor: String)

implicit val messageCodec: JsonValueCodec[Message] = {
  implicit val intCodec: JsonValueCodec[Int] = new JsonValueCodec[Int] {
    override def decodeValue(in: JsonReader, default: Int): Int =
      if (in.isNextToken('[')) {
        var i = 0
        if (!in.isNextToken(']')) {
          in.rollbackToken()
          while ({
            in.skip()
            i += 1
            in.isNextToken(',')
          }) ()
          if (!in.isCurrentToken(']')) in.arrayEndOrCommaError()
        }
        i
      } else in.readNullOrTokenError(default, '[')

    override def encodeValue(x: Int, out: JsonWriter): _root_.scala.Unit = {
      out.writeArrayStart()
      var i = x
      while (i > 0) {
        out.writeNull()
        i -= 1
      }
      out.writeArrayEnd()
    }

    override def nullValue: Int = 0
  }

  JsonCodecMaker.make[Message]
}

val json1 =
  """{
    |   "myArray":[
    |      {
    |         "multipleJsonObjects": "Here"
    |      }
    |   ],
    |   "cursor":"abc"
    |}""".stripMargin.getBytes(StandardCharsets.UTF_8)

assert(readFromArray[Message](json1) == Message(1, "abc"))

val json2 = """{"myArray":[null,null,null],"cursor":"www"}""".getBytes(StandardCharsets.UTF_8)

assert(readFromArray[Message](json2) == Message(3, "www"))
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Andriy Plokhotnyuk
  • 7,883
  • 2
  • 44
  • 68