Switch SettingQueryResponse to JValue, implement JValueFormat

This commit is contained in:
Dale Wijnand 2017-03-20 16:44:57 +00:00
parent f2b70de538
commit 43eec230e6
No known key found for this signature in database
GPG Key ID: 4F256E3D151DF5EF
9 changed files with 90 additions and 19 deletions

View File

@ -181,7 +181,8 @@ lazy val protocolProj = (project in file("protocol")).
testedBaseSettings,
name := "Protocol",
libraryDependencies ++= Seq(sjsonNewScalaJson),
sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala"
sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala",
contrabandFormatsForType in generateContrabands in Compile := ContrabandConfig.getFormats
).
configure(addSbtUtilLogging)
@ -211,6 +212,7 @@ lazy val mainSettingsProj = (project in file("main-settings")).
// The main integration project for sbt. It brings all of the projects together, configures them, and provides for overriding conventions.
lazy val mainProj = (project in file("main")).
dependsOn(actionsProj, mainSettingsProj, runProj, commandProj).
disablePlugins(SbtScalariform).
settings(
testedBaseSettings,
name := "Main",

View File

@ -6,9 +6,10 @@ package internal
package server
import java.net.URI
import scala.json.ast.unsafe.JValue
import scala.util.{ Left, Right }
import sbt.librarymanagement.LibraryManagementCodec._
import sbt.protocol._
import sjsonnew._
import sjsonnew.support.scalajson.unsafe._
object SettingQuery {
@ -86,25 +87,30 @@ object SettingQuery {
case x => Right(x)
}
def toJsonStringStrict[A: Manifest](x: A): Either[String, String] =
def toJsonStringStrict[A: Manifest](x: A): Either[String, JValue] =
JsonFormatRegistry.lookup[A]
.toRight(s"JsonWriter for ${manifest[A]} not found")
.map(implicit jsonWriter => CompactPrinter(Converter.toJsonUnsafe(x)))
.map(implicit jsonWriter => Converter toJsonUnsafe x)
def toJsonString[A: Manifest](x: A): String =
def toJson[A: Manifest](x: A): JValue =
toJsonStringStrict(x) match {
case Right(s) => s
case Left(_) => x.toString
case Right(j) => j
case Left(_) => Converter toJsonUnsafe x.toString
}
def getSettingJsonStringValue[A](structure: BuildStructure, key: Def.ScopedKey[A]): Either[String, String] =
getSettingValue(structure, key) map (toJsonString(_)(key.key.manifest))
def getSettingJsonStringValue[A](structure: BuildStructure, key: Def.ScopedKey[A]): Either[String, JValue] =
getSettingValue(structure, key) map (toJson(_)(key.key.manifest))
def handleSettingQuery(req: SettingQuery, structure: BuildStructure): SettingQueryResponse = {
val key = Parser.parse(req.setting, scopedKeyParser(structure))
val result: Either[String, String] = key flatMap (getSettingJsonStringValue(structure, _))
val result: Either[String, JValue] = key flatMap (getSettingJsonStringValue(structure, _))
SettingQueryResponse(result.merge)
val finalResult: JValue = result match {
case Right(j) => j
case Left(s) => Converter toJsonUnsafe s
}
SettingQueryResponse(finalResult)
}
}

View File

@ -22,6 +22,7 @@ object ContrabandConfig {
case "Option" | "Set" | "scala.Vector" => { tpe => getFormats(oneArg(tpe)) }
case "Map" | "Tuple2" | "scala.Tuple2" => { tpe => twoArgs(tpe).flatMap(getFormats) }
case "Int" | "Long" => { _ => Nil }
case "scala.json.ast.unsafe.JValue" => { _ => "sbt.internal.JValueFormat" :: Nil }
}
/** Returns the list of formats required to encode the given `TpeRef`. */

View File

@ -5,7 +5,7 @@
// DO NOT EDIT MANUALLY
package sbt.protocol
final class SettingQueryResponse private (
val value: String) extends sbt.protocol.EventMessage() with Serializable {
val value: scala.json.ast.unsafe.JValue) extends sbt.protocol.EventMessage() with Serializable {
@ -19,14 +19,14 @@ final class SettingQueryResponse private (
override def toString: String = {
"SettingQueryResponse(" + value + ")"
}
protected[this] def copy(value: String = value): SettingQueryResponse = {
protected[this] def copy(value: scala.json.ast.unsafe.JValue = value): SettingQueryResponse = {
new SettingQueryResponse(value)
}
def withValue(value: String): SettingQueryResponse = {
def withValue(value: scala.json.ast.unsafe.JValue): SettingQueryResponse = {
copy(value = value)
}
}
object SettingQueryResponse {
def apply(value: String): SettingQueryResponse = new SettingQueryResponse(value)
def apply(value: scala.json.ast.unsafe.JValue): SettingQueryResponse = new SettingQueryResponse(value)
}

View File

@ -5,6 +5,6 @@
// DO NOT EDIT MANUALLY
package sbt.protocol.codec
import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder }
trait EventMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.ChannelAcceptedEventFormats with sbt.protocol.codec.LogEventFormats with sbt.protocol.codec.ExecStatusEventFormats with sbt.protocol.codec.SettingQueryResponseFormats =>
trait EventMessageFormats { self: sjsonnew.BasicJsonProtocol with sbt.protocol.codec.ChannelAcceptedEventFormats with sbt.protocol.codec.LogEventFormats with sbt.protocol.codec.ExecStatusEventFormats with sbt.internal.JValueFormat with sbt.protocol.codec.SettingQueryResponseFormats =>
implicit lazy val EventMessageFormat: JsonFormat[sbt.protocol.EventMessage] = flatUnionFormat4[sbt.protocol.EventMessage, sbt.protocol.ChannelAcceptedEvent, sbt.protocol.LogEvent, sbt.protocol.ExecStatusEvent, sbt.protocol.SettingQueryResponse]("type")
}

View File

@ -11,6 +11,7 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol
with sbt.protocol.codec.ChannelAcceptedEventFormats
with sbt.protocol.codec.LogEventFormats
with sbt.protocol.codec.ExecStatusEventFormats
with sbt.internal.JValueFormat
with sbt.protocol.codec.SettingQueryResponseFormats
with sbt.protocol.codec.EventMessageFormats
with sbt.protocol.codec.ExecutionEventFormats

View File

@ -5,13 +5,13 @@
// DO NOT EDIT MANUALLY
package sbt.protocol.codec
import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder }
trait SettingQueryResponseFormats { self: sjsonnew.BasicJsonProtocol =>
trait SettingQueryResponseFormats { self: sbt.internal.JValueFormat with sjsonnew.BasicJsonProtocol =>
implicit lazy val SettingQueryResponseFormat: JsonFormat[sbt.protocol.SettingQueryResponse] = new JsonFormat[sbt.protocol.SettingQueryResponse] {
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.protocol.SettingQueryResponse = {
jsOpt match {
case Some(js) =>
unbuilder.beginObject(js)
val value = unbuilder.readField[String]("value")
val value = unbuilder.readField[scala.json.ast.unsafe.JValue]("value")
unbuilder.endObject()
sbt.protocol.SettingQueryResponse(value)
case None =>

View File

@ -41,7 +41,7 @@ type ExecStatusEvent implements EventMessage {
}
type SettingQueryResponse implements EventMessage {
value: String!
value: scala.json.ast.unsafe.JValue!
}
# enum Status {

View File

@ -0,0 +1,61 @@
/*
* Copyright (C) 2017 Lightbend Inc. <http://www.lightbend.com>
*/
package sbt
package internal
import sjsonnew.{ JsonWriter => JW, JsonReader => JR, JsonFormat => JF, _ }
import scala.json.ast.unsafe._
trait JValueFormat { self: sjsonnew.BasicJsonProtocol =>
/** Define a JsonWriter for the type T wrapper of underlying type U given JsonWriter[U] and T => U. */
def unlift[T, U](unlift: T => U)(implicit z: JW[U]): JW[T] = new JW[T] {
def write[J](w: T, b: Builder[J]) = z.write(unlift(w), b)
}
/** Define a JsonReader for the type T wrapper of underlying type U given JsonReader[U] and U => T. */
def lift[T, U](lift: U => T)(implicit z: JR[U]): JR[T] = new JR[T] {
def read[J](j: Option[J], u: Unbuilder[J]): T = lift(z.read(j, u))
}
@inline def ?[A](implicit z: A): A = z
implicit val JNullJW: JW[JNull.type] = new JW[JNull.type] { def write[J](x: JNull.type, b: Builder[J]) = b.writeNull() }
implicit val JNullJR: JR[JNull.type] = new JR[JNull.type] { def read[J](j: Option[J], u: Unbuilder[J]) = JNull }
implicit val JBooleanJW: JW[JBoolean] = unlift(_.get)
implicit val JBooleanJR: JR[JBoolean] = lift(JBoolean(_))
implicit val JStringJW: JW[JString] = unlift(_.value)
implicit val JStringJR: JR[JString] = lift(JString(_))
implicit val JNumberJW: JW[JNumber] = unlift(x => BigDecimal(x.value))
implicit val JNumberJR: JR[JNumber] = lift((x: BigDecimal) => JNumber(x.toString))
implicit lazy val JArrayJW: JW[JArray] = unlift[JArray, Array[JValue]](_.value)
implicit lazy val JObjectJW: JW[JObject] = new JW[JObject] {
def write[J](x: JObject, b: Builder[J]) = {
b.beginObject()
x.value foreach (jsonField => JValueJW.addField(jsonField.field, jsonField.value, b))
b.endObject()
}
}
implicit lazy val JValueJW: JW[JValue] = new JW[JValue] {
def write[J](x: JValue, b: Builder[J]) = x match {
case x: JNull.type => ?[JW[JNull.type]].write(x, b)
case x: JBoolean => ?[JW[JBoolean]].write(x, b)
case x: JString => ?[JW[JString]].write(x, b)
case x: JNumber => ?[JW[JNumber]].write(x, b)
case x: JObject => ?[JW[JObject]].write(x, b)
case x: JArray => ?[JW[JArray]].write(x, b)
}
}
implicit lazy val JValueJR: JR[JValue] = new JR[JValue] {
def read[J](j: Option[J], u: Unbuilder[J]) = ??? // Is this even possible? with no Manifest[J]?
}
implicit lazy val JValueJF: JF[JValue] = jsonFormat[JValue](JValueJR, JValueJW)
}