Fix handling id in jsonrpc model

Fix #3861
This commit is contained in:
tiqwab 2018-03-16 21:46:09 +09:00
parent 6abf4c9e00
commit a5119a411c
2 changed files with 33 additions and 5 deletions

View File

@ -24,7 +24,10 @@ trait JsonRpcRequestMessageFormats {
val id = try {
unbuilder.readField[String]("id")
} catch {
case _: Throwable => unbuilder.readField[Long]("id").toString
case _: Throwable => {
val prefix = "\u2668" // Append prefix to show the original type was Number
prefix + unbuilder.readField[Long]("id").toString
}
}
val method = unbuilder.readField[String]("method")
val params = unbuilder.lookupField("params") map {

View File

@ -7,8 +7,8 @@
package sbt.internal.protocol.codec
import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError }
import sjsonnew.shaded.scalajson.ast.unsafe.JValue
import _root_.sjsonnew.{ Builder, JsonFormat, Unbuilder, deserializationError }
import sjsonnew.shaded.scalajson.ast.unsafe._
trait JsonRpcResponseMessageFormats {
self: sbt.internal.util.codec.JValueFormats
@ -45,10 +45,35 @@ trait JsonRpcResponseMessageFormats {
}
override def write[J](obj: sbt.internal.protocol.JsonRpcResponseMessage,
builder: Builder[J]): Unit = {
// Parse given id to Long or String judging by prefix
def parseId(str: String): Either[Long, String] = {
if (str.startsWith("\u2668")) Left(str.substring(1).toLong)
else Right(str)
}
def parseResult(jValue: JValue): JValue = jValue match {
case JObject(jFields) =>
val replaced = jFields map {
case field @ JField("execId", JString(str)) =>
parseId(str) match {
case Right(strId) => field.copy(value = JString(strId))
case Left(longId) => field.copy(value = JNumber(longId))
}
case other =>
other
}
JObject(replaced)
case other =>
other
}
builder.beginObject()
builder.addField("jsonrpc", obj.jsonrpc)
builder.addField("id", obj.id)
builder.addField("result", obj.result)
obj.id foreach { id =>
parseId(id) match {
case Right(strId) => builder.addField("id", strId)
case Left(longId) => builder.addField("id", longId)
}
}
builder.addField("result", obj.result map parseResult)
builder.addField("error", obj.error)
builder.endObject()
}