spray / spray-json

A lightweight, clean and simple JSON implementation in Scala
Apache License 2.0
969 stars 190 forks source link

Cannot parse as Long from String format field #349

Open carbonshow opened 2 years ago

carbonshow commented 2 years ago

According to the protobuf issue, int64, uint64 type is serialized into string due to a Javascript precision problem. And it seems spray cannot read the string field as Long type.

for example:

  1. case class definition: case class Test(id: String, timestamp: Long)
  2. protobuf IDL definition:
    message Test {
       string id = 1;
       int64 timestamp = 2;
    }

the output string from protobuf json looks like:

{
  "id": "xyz",
  "timestamp": "1648867560"
}

When spray parse the timestamp field as Long, got the exception: "Expected Long as JsNumber, but got "1648867560" "

Suggest: Add the String match case for LongJsonFormat:

implicit object LongJsonFormat extends JsonFormat[Long] {
    def write(x: Long) = JsNumber(x)
    def read(value: JsValue) = value match {
      case JsNumber(x) if x.isValidLong => x.longValue
      case JsString(x) => BigDecimal(x).longValue
      case x => deserializationError("Expected Long as JsNumber, but got " + x)
    }
  }