Skip to content

Instantly share code, notes, and snippets.

@wolfendale
Last active December 8, 2015 15:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wolfendale/d25a345ef7655bfb7ed6 to your computer and use it in GitHub Desktop.
Save wolfendale/d25a345ef7655bfb7ed6 to your computer and use it in GitHub Desktop.
Either Mapping
package forms
import play.api.data.{FormError, Mapping}
import play.api.data.validation.Constraint
case class EitherMapping[L, R](
lmapping: Mapping[L],
rmapping: Mapping[R],
key: String = "",
constraints: Seq[Constraint[Either[L, R]]] = Nil
) extends Mapping[Either[L, R]] {
override def verifying(constraints: Constraint[Either[L, R]]*): Mapping[Either[L, R]] =
copy(constraints = this.constraints ++ constraints.toSeq)
override def bind(data: Map[String, String]): Either[Seq[FormError], Either[L, R]] =
lmapping.bind(data) match {
case Left(errorsO) =>
rmapping.bind(data) match {
case Left(errorsI) => Left(errorsI)
case Right(r) => Right(Right(r))
}
case Right(r) => Right(Left(r))
}
override def unbind(value: Either[L, R]): Map[String, String] =
value match {
case Left(l) => lmapping.unbind(l)
case Right(r) => rmapping.unbind(r)
}
override def unbindAndValidate(value: Either[L, R]): (Map[String, String], Seq[FormError]) = {
val errors = collectErrors(value)
value match {
case Left(l) => {
val r = lmapping.unbindAndValidate(l)
r._1 -> (r._2 ++ errors)
}
case Right(l) => {
val r = rmapping.unbindAndValidate(l)
r._1 -> (r._2 ++ errors)
}
}
}
override def withPrefix(prefix: String): Mapping[Either[L, R]] =
copy(key = s"$prefix.$key", lmapping = lmapping.withPrefix(prefix), rmapping = rmapping.withPrefix(prefix))
override val mappings: Seq[Mapping[_]] = Nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment