sjson.json.Generic.scala Maven / Gradle / Ivy
package sjson
package json
import dispatch.json._
trait Generic extends Protocol {
import JsonSerialization._
implicit def listFormat[T](implicit fmt : Format[T]) : Format[List[T]];
def viaSeq[S <: Iterable[T], T] (f : Seq[T] => S) (implicit fmt : Format[T]) : Format[S] = new Format[S] {
def writes(ts: S) = JsArray(ts.map(t => tojson(t)(fmt)).toList)
def reads(json: JsValue) = json match {
case JsArray(ts) => f(ts.map(t => fromjson[T](t)))
case _ => throw new RuntimeException("Collection expected")
}
}
/**
* Use this when you would wrap a value in a case class
*
*
* case class Name(name: String)
* implicit val NameFormat: Format[Name] = wrap[Name, String]("name")(_.name, Name)
*
* val n = Name("debasish ghosh")
* fromjson[Name](tojson(n)) should equal(n)
*
*/
def wrap[S, T](name: String)(to : S => T, from : T => S)(implicit fmt : Format[T]) = new Format[S]{
def writes(s : S) = JsObject(List((tojson(name).asInstanceOf[JsString], tojson(to(s)))))
def reads(js : JsValue) = js match {
case JsObject(m) =>
from(fromjson[T](m(JsString(name))))
case _ => throw new RuntimeException("Object expected")
}
}
/**
* Lazy wrapper around serialization. Useful when you want to serialize mutually recursive structures.
*/
def lazyFormat[S](fmt : => Format[S]) = new Format[S]{
lazy val delegate = fmt;
def reads(js : JsValue) = delegate.reads(js);
def writes(s : S) = delegate.writes(s);
}
def asProduct2[S, T1,T2](f1: String,f2: String)(apply : (T1,T2) => S)(unapply : S => Product2[T1,T2])(implicit bin1: Format[T1],bin2: Format[T2]) = new Format[S]{
def writes(s: S) = {
val product = unapply(s)
JsObject(
List(
(tojson(f1).asInstanceOf[JsString], tojson(product._1)),
(tojson(f2).asInstanceOf[JsString], tojson(product._2))
))
}
def reads(js: JsValue) = js match {
case JsObject(m) => // m is the Map
apply(
fromjson[T1](m(JsString(f1))),
fromjson[T2](m(JsString(f2)))
)
case _ => throw new RuntimeException("object expected")
}
}
def asProduct3[S, T1,T2,T3](f1: String,f2: String,f3: String)(apply : (T1,T2,T3) => S)(unapply : S => Product3[T1,T2,T3])(implicit bin1: Format[T1],bin2: Format[T2],bin3: Format[T3]) = new Format[S]{
def writes(s: S) = {
val product = unapply(s)
JsObject(
List(
(tojson(f1).asInstanceOf[JsString], tojson(product._1)),
(tojson(f2).asInstanceOf[JsString], tojson(product._2)),
(tojson(f3).asInstanceOf[JsString], tojson(product._3))
))
}
def reads(js: JsValue) = js match {
case JsObject(m) => // m is the Map
apply(
fromjson[T1](m(JsString(f1))),
fromjson[T2](m(JsString(f2))),
fromjson[T3](m(JsString(f3)))
)
case _ => throw new RuntimeException("object expected")
}
}
def asProduct4[S, T1,T2,T3,T4](f1: String,f2: String,f3: String,f4: String)(apply : (T1,T2,T3,T4) => S)(unapply : S => Product4[T1,T2,T3,T4])(implicit bin1: Format[T1],bin2: Format[T2],bin3: Format[T3],bin4: Format[T4]) = new Format[S]{
def writes(s: S) = {
val product = unapply(s)
JsObject(
List(
(tojson(f1).asInstanceOf[JsString], tojson(product._1)),
(tojson(f2).asInstanceOf[JsString], tojson(product._2)),
(tojson(f3).asInstanceOf[JsString], tojson(product._3)),
(tojson(f4).asInstanceOf[JsString], tojson(product._4))
))
}
def reads(js: JsValue) = js match {
case JsObject(m) => // m is the Map
apply(
fromjson[T1](m(JsString(f1))),
fromjson[T2](m(JsString(f2))),
fromjson[T3](m(JsString(f3))),
fromjson[T4](m(JsString(f4)))
)
case _ => throw new RuntimeException("object expected")
}
}
def asProduct5[S, T1,T2,T3,T4,T5](f1: String,f2: String,f3: String,f4: String,f5: String)(apply : (T1,T2,T3,T4,T5) => S)(unapply : S => Product5[T1,T2,T3,T4,T5])(implicit bin1: Format[T1],bin2: Format[T2],bin3: Format[T3],bin4: Format[T4],bin5: Format[T5]) = new Format[S]{
def writes(s: S) = {
val product = unapply(s)
JsObject(
List(
(tojson(f1).asInstanceOf[JsString], tojson(product._1)),
(tojson(f2).asInstanceOf[JsString], tojson(product._2)),
(tojson(f3).asInstanceOf[JsString], tojson(product._3)),
(tojson(f4).asInstanceOf[JsString], tojson(product._4)),
(tojson(f5).asInstanceOf[JsString], tojson(product._5))
))
}
def reads(js: JsValue) = js match {
case JsObject(m) => // m is the Map
apply(
fromjson[T1](m(JsString(f1))),
fromjson[T2](m(JsString(f2))),
fromjson[T3](m(JsString(f3))),
fromjson[T4](m(JsString(f4))),
fromjson[T5](m(JsString(f5)))
)
case _ => throw new RuntimeException("object expected")
}
}
def asProduct6[S, T1,T2,T3,T4,T5,T6](f1: String,f2: String,f3: String,f4: String,f5: String,f6: String)(apply : (T1,T2,T3,T4,T5,T6) => S)(unapply : S => Product6[T1,T2,T3,T4,T5,T6])(implicit bin1: Format[T1],bin2: Format[T2],bin3: Format[T3],bin4: Format[T4],bin5: Format[T5],bin6: Format[T6]) = new Format[S]{
def writes(s: S) = {
val product = unapply(s)
JsObject(
List(
(tojson(f1).asInstanceOf[JsString], tojson(product._1)),
(tojson(f2).asInstanceOf[JsString], tojson(product._2)),
(tojson(f3).asInstanceOf[JsString], tojson(product._3)),
(tojson(f4).asInstanceOf[JsString], tojson(product._4)),
(tojson(f5).asInstanceOf[JsString], tojson(product._5)),
(tojson(f6).asInstanceOf[JsString], tojson(product._6))
))
}
def reads(js: JsValue) = js match {
case JsObject(m) => // m is the Map
apply(
fromjson[T1](m(JsString(f1))),
fromjson[T2](m(JsString(f2))),
fromjson[T3](m(JsString(f3))),
fromjson[T4](m(JsString(f4))),
fromjson[T5](m(JsString(f5))),
fromjson[T6](m(JsString(f6)))
)
case _ => throw new RuntimeException("object expected")
}
}
def asProduct7[S, T1,T2,T3,T4,T5,T6,T7](f1: String,f2: String,f3: String,f4: String,f5: String,f6: String,f7: String)(apply : (T1,T2,T3,T4,T5,T6,T7) => S)(unapply : S => Product7[T1,T2,T3,T4,T5,T6,T7])(implicit bin1: Format[T1],bin2: Format[T2],bin3: Format[T3],bin4: Format[T4],bin5: Format[T5],bin6: Format[T6],bin7: Format[T7]) = new Format[S]{
def writes(s: S) = {
val product = unapply(s)
JsObject(
List(
(tojson(f1).asInstanceOf[JsString], tojson(product._1)),
(tojson(f2).asInstanceOf[JsString], tojson(product._2)),
(tojson(f3).asInstanceOf[JsString], tojson(product._3)),
(tojson(f4).asInstanceOf[JsString], tojson(product._4)),
(tojson(f5).asInstanceOf[JsString], tojson(product._5)),
(tojson(f6).asInstanceOf[JsString], tojson(product._6)),
(tojson(f7).asInstanceOf[JsString], tojson(product._7))
))
}
def reads(js: JsValue) = js match {
case JsObject(m) => // m is the Map
apply(
fromjson[T1](m(JsString(f1))),
fromjson[T2](m(JsString(f2))),
fromjson[T3](m(JsString(f3))),
fromjson[T4](m(JsString(f4))),
fromjson[T5](m(JsString(f5))),
fromjson[T6](m(JsString(f6))),
fromjson[T7](m(JsString(f7)))
)
case _ => throw new RuntimeException("object expected")
}
}
def asProduct8[S, T1,T2,T3,T4,T5,T6,T7,T8](f1: String,f2: String,f3: String,f4: String,f5: String,f6: String,f7: String,f8: String)(apply : (T1,T2,T3,T4,T5,T6,T7,T8) => S)(unapply : S => Product8[T1,T2,T3,T4,T5,T6,T7,T8])(implicit bin1: Format[T1],bin2: Format[T2],bin3: Format[T3],bin4: Format[T4],bin5: Format[T5],bin6: Format[T6],bin7: Format[T7],bin8: Format[T8]) = new Format[S]{
def writes(s: S) = {
val product = unapply(s)
JsObject(
List(
(tojson(f1).asInstanceOf[JsString], tojson(product._1)),
(tojson(f2).asInstanceOf[JsString], tojson(product._2)),
(tojson(f3).asInstanceOf[JsString], tojson(product._3)),
(tojson(f4).asInstanceOf[JsString], tojson(product._4)),
(tojson(f5).asInstanceOf[JsString], tojson(product._5)),
(tojson(f6).asInstanceOf[JsString], tojson(product._6)),
(tojson(f7).asInstanceOf[JsString], tojson(product._7)),
(tojson(f8).asInstanceOf[JsString], tojson(product._8))
))
}
def reads(js: JsValue) = js match {
case JsObject(m) => // m is the Map
apply(
fromjson[T1](m(JsString(f1))),
fromjson[T2](m(JsString(f2))),
fromjson[T3](m(JsString(f3))),
fromjson[T4](m(JsString(f4))),
fromjson[T5](m(JsString(f5))),
fromjson[T6](m(JsString(f6))),
fromjson[T7](m(JsString(f7))),
fromjson[T8](m(JsString(f8)))
)
case _ => throw new RuntimeException("object expected")
}
}
def asProduct9[S, T1,T2,T3,T4,T5,T6,T7,T8,T9](f1: String,f2: String,f3: String,f4: String,f5: String,f6: String,f7: String,f8: String,f9: String)(apply : (T1,T2,T3,T4,T5,T6,T7,T8,T9) => S)(unapply : S => Product9[T1,T2,T3,T4,T5,T6,T7,T8,T9])(implicit bin1: Format[T1],bin2: Format[T2],bin3: Format[T3],bin4: Format[T4],bin5: Format[T5],bin6: Format[T6],bin7: Format[T7],bin8: Format[T8],bin9: Format[T9]) = new Format[S]{
def writes(s: S) = {
val product = unapply(s)
JsObject(
List(
(tojson(f1).asInstanceOf[JsString], tojson(product._1)),
(tojson(f2).asInstanceOf[JsString], tojson(product._2)),
(tojson(f3).asInstanceOf[JsString], tojson(product._3)),
(tojson(f4).asInstanceOf[JsString], tojson(product._4)),
(tojson(f5).asInstanceOf[JsString], tojson(product._5)),
(tojson(f6).asInstanceOf[JsString], tojson(product._6)),
(tojson(f7).asInstanceOf[JsString], tojson(product._7)),
(tojson(f8).asInstanceOf[JsString], tojson(product._8)),
(tojson(f9).asInstanceOf[JsString], tojson(product._9))
))
}
def reads(js: JsValue) = js match {
case JsObject(m) => // m is the Map
apply(
fromjson[T1](m(JsString(f1))),
fromjson[T2](m(JsString(f2))),
fromjson[T3](m(JsString(f3))),
fromjson[T4](m(JsString(f4))),
fromjson[T5](m(JsString(f5))),
fromjson[T6](m(JsString(f6))),
fromjson[T7](m(JsString(f7))),
fromjson[T8](m(JsString(f8))),
fromjson[T9](m(JsString(f9)))
)
case _ => throw new RuntimeException("object expected")
}
}
/**
* one sample for i=3 that will be generated is:
* def asProduct3[S, T1, T2, T3](f1: String, f2: String, f3: String)(apply : (T1, T2, T3) => S)(unapply : S => Product3[T1, T2, T3])(implicit bin1: Format[T1], bin2: Format[T2], bin3: Format[T3]) = new Format[S]{
* def writes(s: S) = {
* val product = unapply(s)
* JsObject(
* List(
* (tojson(f1).asInstanceOf[JsString], tojson(product._1)),
* (tojson(f2).asInstanceOf[JsString], tojson(product._2)),
* (tojson(f3).asInstanceOf[JsString], tojson(product._3))
* ))
* }
* def reads(js: JsValue) = js match {
* case JsObject(m) => // m is the Map
* apply(
* fromjson[T1](m(JsString(f1))),
* fromjson[T2](m(JsString(f2))),
* fromjson[T3](m(JsString(f3)))
* )
* case _ => throw new RuntimeException("object expected")
* }
* }
**/
/**
case class Summand[T](clazz : Class[_], format : Format[T]);
implicit def classToSummand[T](clazz : Class[T])(implicit fmt : Format[T]) : Summand[T] = Summand[T](clazz, fmt);
implicit def formatToSummand[T](format : Format[T])(implicit mf : scala.reflect.Manifest[T]) : Summand[T] =
Summand[T](mf.erasure, format);
def asUnion[S](summands : Summand[_ <: S]*) : Format[S] =
if (summands.length >= 256) error("Sums of 256 or more elements currently not supported");
else
new Format[S]{
val mappings = summands.toArray.zipWithIndex;
def reads(json : JsValue) : S = read(in)(summands(read[Byte](in)).format)
// def writes(ts: S) = JsArray(ts.map(t => tojson(t)(fmt)).toList)
// def reads(json: JsValue) = json match {
def writes(ts: S) = JsArray(ts.map(t => tojson(t)(fmt)).toList)
def writes(out : Output, s : S): Unit =
mappings.find(_._1.clazz.isInstance(s)) match {
case Some( (sum, i) ) => writeSum(out, s, sum, i)
case None => error("No known sum type for object " + s);
}
private def writeSum[T](out : Output, s : S, sum : Summand[T], i : Int) {
write(out, i.toByte);
// 2.7/2.8 compatibility: cast added by MH
write(out, sum.clazz.cast(s).asInstanceOf[T])(sum.format);
}
}
**/
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy