Skip to content

Instantly share code, notes, and snippets.

@realpeterz
Last active July 24, 2021 01:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save realpeterz/26cfd708575b75d26f82b4cc103b9f9b to your computer and use it in GitHub Desktop.
Save realpeterz/26cfd708575b75d26f82b4cc103b9f9b to your computer and use it in GitHub Desktop.
Play Json Format helper for value classes
import play.api.libs.functional.syntax._
import play.api.libs.json.{Format, Json}
object SingleFieldFormat {
def format[A, B](f: A => B, g: B => A)(implicit fa: Format[A]) = fa.inmap(f, g)
// expanded:
// syntax.toInvariantFunctorOps(fa)(Format.invariantFunctorFormat).inmap(f, g)
// inmap's underlying:
// Format[B](fa.map(f), Writes[B](b => fa.writes(g(b))))
}
case class AgentId(id: String) extends AnyVal
object AgentId {
def fromIntId(i: Int) = i match {
case 47 => apply("Hitman: Agent 47")
case x: Int => apply(x.toString)
}
implicit val format = SingleFieldFormat.format(AgentId.apply, unlift(AgentId.unapply))
}
case class Profile(userId: AgentId, dob: String)
object Profile {
implicit val format = Json.format[Profile]
}
val profile = Profile(AgentId.fromIntId(47), "09/05/1964")
val profileSerialized: String = Json.stringify(Json.toJson(profile))
val profileDeserialized: Profile = Json.fromJson[Profile](Json.parse(profileSerialized)).get
assert(profileDeserialized == profile)
// Console output:
// profile: Profile = Profile(AgentId(Hitman: Agent 47),09/05/1964)
// profileSerialized: String = {"userId":"Hitman: Agent 47","dob":"09/05/1964"}
// profileDeserialized: Profile = Profile(AgentId(Hitman: Agent 47),09/05/1964)
// res0: Unit = ()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment