Last active
July 24, 2021 01:28
-
-
Save realpeterz/26cfd708575b75d26f82b4cc103b9f9b to your computer and use it in GitHub Desktop.
Play Json Format helper for value classes
This file contains 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.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