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