Last active
October 20, 2015 22:54
-
-
Save unthingable/5f7ad3aca14653c79e1e to your computer and use it in GitHub Desktop.
structural variance in json objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object lisMessages { | |
case class PayloadData(name: String, newValue: JsValue, oldValue: JsValue) | |
case class LisPayloadA[C:Format, D:Format] ( | |
uuid : String, | |
timestamp : String, | |
source : String, | |
context : C, | |
model : String, | |
data : D, | |
event : String, | |
uid : String | |
) { | |
lazy val rkey = s"$source.$model.$event" | |
} | |
def lpaFormat[C:Format, D:Format]: Format[LisPayloadA[C, D]] = ( | |
(__ \ "uuid" ).format[String] and | |
(__ \ "timestamp" ).format[String] and | |
(__ \ "source" ).format[String] and | |
(__ \ "context" ).format[C] and | |
(__ \ "model" ).format[String] and | |
(__ \ "data" ).format[D] and | |
(__ \ "event" ).format[String] and | |
(__ \ "uid" ).format[String] | |
)(LisPayloadA.apply[C,D], unlift(LisPayloadA.unapply[C,D])) | |
// Different message types | |
type BompPayload = LisPayloadA[JsValue, List[PayloadData]] | |
type LisPayload = LisPayloadA[JsValue, JsValue] | |
implicit val bmpFormat: Format[BompPayload] = lpaFormat[JsValue, List[PayloadData]] | |
implicit val lisFormat: Format[LisPayload] = lpaFormat[JsValue, JsValue] | |
def dataMap(pl:BompPayload) = pl.data.map(x => (x.name, x)).toMap | |
implicit val payloadDataReads: Reads[PayloadData] = ( | |
__(0).read[String] and | |
__(1).read[JsValue] and | |
__(2).read[JsValue] | |
)(PayloadData.apply _) | |
// not as elegant, but how else to indicate we're creating an Array? | |
implicit val payloadDataWrites = new Writes[PayloadData] { | |
def writes(p: PayloadData): JsValue = { | |
Json.arr(p.name, p.newValue, p.oldValue) | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object experiment { | |
trait T[C<:Format[_]] { | |
def apply(a:String, b:String, c: C) = { new X(a,b,c) } | |
} | |
case class X[C<:Format[_]] ( | |
val a: String, | |
val b: String, | |
val c: C | |
) | |
// Extending X requires both a trait (for the apply method) for the object | |
// and a class for a type. We also have to repeat the type parameter. Is there a simpler way? | |
object A extends T[List[String]] | |
type A = X[List[String]] | |
object B extends T[Boolean] | |
type B = X[Boolean] | |
// ... etc | |
val a:A = A("foo", "bar", List("xyz")) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment