mirror of https://github.com/sbt/sbt.git
Move HListFormats to collection to drop cache->collection dep
Looks like the reason that util-cache depended on util-collection was to define the sjson-new formats (HListFormats) for util-collection's HList. Given that util-collection already depends on sjsonnew, HListFormats can also be defined in util-collection. All that was left then was (a) HListFormatSpec requires sjsonnewScalaJson, so that was added in test scope, and (b) HListFormats had to be dropped from sbt.util.CacheImplicits - HListFormats will have to be imported and/or mixed-in where required downstream. For importing convenience I defined a companion object.
This commit is contained in:
parent
068b46cbd1
commit
cc3f46f996
|
|
@ -0,0 +1,70 @@
|
|||
package sbt
|
||||
package internal
|
||||
package util
|
||||
|
||||
import sjsonnew._
|
||||
import Types.:+:
|
||||
|
||||
trait HListFormats {
|
||||
implicit val lnilFormat1: JsonFormat[HNil] = forHNil(HNil)
|
||||
implicit val lnilFormat2: JsonFormat[HNil.type] = forHNil(HNil)
|
||||
|
||||
private def forHNil[A <: HNil](hnil: A): JsonFormat[A] = new JsonFormat[A] {
|
||||
def write[J](x: A, builder: Builder[J]): Unit = {
|
||||
builder.beginArray()
|
||||
builder.endArray()
|
||||
}
|
||||
|
||||
def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): A = jsOpt match {
|
||||
case None => hnil
|
||||
case Some(js) => unbuilder.beginArray(js); unbuilder.endArray(); hnil
|
||||
}
|
||||
}
|
||||
|
||||
implicit def hconsFormat[H, T <: HList](implicit hf: JsonFormat[H], tf: HListJF[T]): JsonFormat[H :+: T] =
|
||||
new JsonFormat[H :+: T] {
|
||||
def write[J](hcons: H :+: T, builder: Builder[J]) = {
|
||||
builder.beginArray()
|
||||
hf.write(hcons.head, builder)
|
||||
tf.write(hcons.tail, builder)
|
||||
builder.endArray()
|
||||
}
|
||||
|
||||
def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]) = jsOpt match {
|
||||
case None => HCons(hf.read(None, unbuilder), tf.read(None, unbuilder))
|
||||
case Some(js) =>
|
||||
unbuilder.beginArray(js)
|
||||
val hcons = HCons(hf.read(Some(unbuilder.nextElement), unbuilder), tf.read(Some(js), unbuilder))
|
||||
unbuilder.endArray()
|
||||
hcons
|
||||
}
|
||||
}
|
||||
|
||||
trait HListJF[A <: HList] {
|
||||
def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): A
|
||||
def write[J](obj: A, builder: Builder[J]): Unit
|
||||
}
|
||||
|
||||
implicit def hconsHListJF[H, T <: HList](implicit hf: JsonFormat[H], tf: HListJF[T]): HListJF[H :+: T] =
|
||||
new HListJF[H :+: T] {
|
||||
def write[J](hcons: H :+: T, builder: Builder[J]) = {
|
||||
hf.write(hcons.head, builder)
|
||||
tf.write(hcons.tail, builder)
|
||||
}
|
||||
|
||||
def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]) = jsOpt match {
|
||||
case None => HCons(hf.read(None, unbuilder), tf.read(None, unbuilder))
|
||||
case Some(js) => HCons(hf.read(Some(unbuilder.nextElement), unbuilder), tf.read(Some(js), unbuilder))
|
||||
}
|
||||
}
|
||||
|
||||
implicit val lnilHListJF1: HListJF[HNil] = hnilHListJF(HNil)
|
||||
implicit val lnilHListJF2: HListJF[HNil.type] = hnilHListJF(HNil)
|
||||
|
||||
implicit def hnilHListJF[A <: HNil](hnil: A): HListJF[A] = new HListJF[A] {
|
||||
def write[J](hcons: A, builder: Builder[J]) = ()
|
||||
def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]) = hnil
|
||||
}
|
||||
}
|
||||
|
||||
object HListFormats extends HListFormats
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package sbt
|
||||
package internal
|
||||
package util
|
||||
|
||||
import scalajson.ast.unsafe._
|
||||
import sjsonnew._, BasicJsonProtocol._, support.scalajson.unsafe._
|
||||
import HListFormats._
|
||||
|
||||
class HListFormatSpec extends UnitSpec {
|
||||
val quux = 23 :+: "quux" :+: true :+: HNil
|
||||
|
||||
it should "round trip quux" in assertRoundTrip(quux)
|
||||
it should "round trip hnil" in assertRoundTrip(HNil)
|
||||
|
||||
it should "have a flat structure for quux" in assertJsonString(quux, """[23,"quux",true]""")
|
||||
it should "have a flat structure for hnil" in assertJsonString(HNil, "[]")
|
||||
|
||||
def assertRoundTrip[A: JsonWriter: JsonReader](x: A) = {
|
||||
val jsonString: String = toJsonString(x)
|
||||
val jValue: JValue = Parser.parseUnsafe(jsonString)
|
||||
val y: A = Converter.fromJson[A](jValue).get
|
||||
assert(x === y)
|
||||
}
|
||||
|
||||
def assertJsonString[A: JsonWriter](x: A, s: String) = assert(toJsonString(x) === s)
|
||||
|
||||
def toJsonString[A: JsonWriter](x: A): String = CompactPrinter(Converter.toJson(x).get)
|
||||
}
|
||||
Loading…
Reference in New Issue