Last active
July 27, 2018 18:58
-
-
Save tanitanin/607ce3c1c270fb3527f2 to your computer and use it in GitHub Desktop.
QueryStringBindable and Formatter for Option[T] ( @ Play Framework 2.x )
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
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