Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Play Framework Form Mappings to JSON
package controllers.utils
import play.api.data.validation.Constraint
import play.api.libs.json._
import play.api.data._
import play.api.data.Forms._
/**
* @author Herman Banken
* @since 11/11/16.
*/
object FormUtils {
def anyFormat(in: Any): JsValue = in match {
case i: Int => JsNumber(i)
case i: Long => JsNumber(i)
case i: BigDecimal => JsNumber(i)
case s: String => JsString(s)
case s => JsString(s.toString)
}
implicit val constraintFormat: Writes[Constraint[Any]] = Writes {
case constraint => Json.obj(
"name" -> constraint.name,
"args" -> constraint.args.map(anyFormat)
)
}
implicit val mappingFormat: Writes[Mapping[Any]] = Writes.apply(mapping => Json.obj(
"key" -> mapping.key,
"constraints" -> Json.toJson(mapping.constraints.toList),
"format" -> mapping.format.map(f => Json.arr(JsString(f._1), JsArray(f._2.map(anyFormat)))),
"mappings" -> JsArray(mapping.mappings
// Mappings seem to be recursive, at least sometimes. Prevent loop:
.filter(_ != mapping)
.map(_.asInstanceOf[Mapping[Any]])
.map(Json.toJson(_)(mappingFormat)))
))
}
object Example {
import FormUtils._
case class Address(street: String, city: String)
case class UserData(name: String, age: Int, address: Address)
val addressForm = Form(
mapping(
"street" -> text,
"city" -> text(10)
)(Address.apply)(Address.unapply)
)
val userForm = Form(
mapping(
"name" -> text,
"age" -> number,
"address" -> addressForm.mapping
)(UserData.apply)(UserData.unapply)
)
def jsConstaints = Json.toJson(userForm.mapping.asInstanceOf[Mapping[Any]])(mappingFormat)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment