package dispatch.liftjson
import dispatch._
import net.liftweb.json._
import JsonAST._
import JsonDSL._
object Js {
implicit def Request2JsonRequest(r: dispatch.Request) = new JsonRequest(r)
implicit def String2JsonRequest(r: String) = new JsonRequest(new Request(r))
class JsonRequest(r: Request) {
def ># [T](block: JValue => T) = r >- { s => block(JsonParser.parse(s)) }
def as_pretty = ># { js => pretty(render(js))}
}
val str: (JValue => List[String]) = {
case JString(s) => s :: Nil
case _ => Nil
}
val date = str
val int: (JValue => List[BigInt]) = {
case JInt(i) => i :: Nil
case _ => Nil
}
val double: (JValue => List[Double]) = {
case JDouble(d) => d :: Nil
case _ => Nil
}
val bool: (JValue => List[Boolean]) = {
case JBool(b) => b :: Nil
case _ => Nil
}
val obj: (JValue => List[JField]) = {
case JObject(l) => l
case _ => Nil
}
val ary: (JValue => List[JValue]) = {
case JArray(l) => l
case _ => Nil
}
def in[T <: JValue](values: T*): (JValue => List[T]) = { value =>
values filter { _ == value } toList
}
implicit def jvlistcomb(block: JValue => List[JValue]) = new JvListComb(block)
class JvListComb(block: JValue => List[JValue]) {
def ~>[T](next: List[JValue] => T) = block andThen next
def >~>[T](next: JValue => T) = ~> { _ map next }
def >>~>[T](next: JValue => List[T]) = ~> { _ flatMap next }
}
implicit def jvcomb[T](block: JValue => T) = new JvComb(block)
class JvComb[T](block: JValue => T) {
def ~ [O](other: JValue => O) = { jv: JValue => (block(jv), other(jv)) }
}
implicit def jvbind[A <: JValue](list: List[A]) = new JvBind(list)
class JvBind[A <: JValue](list: List[A]) {
def >>=[B](f: A => Iterable[B]) = list.flatMap(f)
}
implicit def sym2op(sym: Symbol) = new SymOp(sym)
class SymOp(sym: Symbol) {
def ?[T](block: JValue => List[T]): JValue => List[T] = {
case JObject(l) => l filter { _.name == sym.name } flatMap { jf => block(jf.value) }
case JField(name, value) if name == sym.name => block(value)
case _ => Nil
}
}
}