Skip to content

Instantly share code, notes, and snippets.

@tanitanin
Last active July 27, 2018 18:58
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanitanin/607ce3c1c270fb3527f2 to your computer and use it in GitHub Desktop.
Save tanitanin/607ce3c1c270fb3527f2 to your computer and use it in GitHub Desktop.
QueryStringBindable and Formatter for Option[T] ( @ Play Framework 2.x )
import play.api.data._
import play.api.data.format._
import play.api.data.format.Formats._
/**
* Option[T]をクエリとして解決するためのバインダ(必須でないパラメータなどに利用することを想定)
* 通常のFormと同様にbindFromRequestして使う
* クエリに該当するキーが含まれていない場合にはFormの値がNoneになる
*
* こんなかんじ (もっときれいに書きたいけど):
*
* case class Query(by: Option[String])
* val qForm = Form( mapping( "by" -> of[Option[String]] )(Query.apply)(Query.unapply) )
* def list = Action { implicit rs =>
* val q = qForm.bindFromRequest.get
* q.by match {
* case Some("id") | None => Ok("Sorted by ID!!")
* case Some("name") => Ok("Sorted by NAME!!)
* }
* }
*
*/
implicit def optionBinder[T: QueryStringBindable](implicit binder: QueryStringBindable[T]) = new QueryStringBindable[Option[T]] {
def bind(key: String, params: Map[String,Seq[String]]): Option[Either[String,Option[T]]] = {
try {
params.contains(key) match {
case false => Some(Right(None))
case true => {
params(key).lastOption match {
case Some(str) => Some(Right(Some(binder.bind(key,params).get.right.get)))
case None => Some(Right(None))
}
}
}
} catch {
case e: IllegalArgumentException => Some(Left("Illegal Argument Exception"))
case e: Exception => Some(Left("Exception"))
}
}
def unbind(key: String, t: Option[T]): String = {
t match {
case None => ""
case Some(v) => {
binder.unbind(key,v)
}
}
}
}
implicit def optionFormatter[T](implicit formatter: Formatter[T]) = new Formatter[Option[T]] {
override val format = formatter.format
def bind(key: String, data: Map[String,String]) = {
data.contains(key) match {
case false => Right(None)
case true => formatter.bind(key,data) match {
case Right(v) => Right(Some(v))
case Left(e) => Left(e)
}
}
}
def unbind(key: String, value: Option[T]) = value match {
case Some(v) => formatter.unbind(key,v)
case None => Map()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment