Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Created December 23, 2014 23:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save xuwei-k/e439479b3b4a6ac04322 to your computer and use it in GitHub Desktop.
Save xuwei-k/e439479b3b4a6ac04322 to your computer and use it in GitHub Desktop.
libraryDependencies += "com.typesafe.play" %% "play-json" % "2.3.7"
resolvers += "typesafe" at "http://typesafe.artifactoryonline.com/typesafe/releases"
scalaVersion := "2.11.4"
import play.api.libs.json._
// https://groups.google.com/d/topic/play-framework/anYvYB-8GYs/discussion
object EitherReadsExample {
implicit def eitherReads[A, B](implicit A: Reads[A], B: Reads[B]): Reads[Either[A, B]] =
Reads[Either[A, B]] { json =>
A.reads(json) match {
case JsSuccess(value, path) => JsSuccess(Left(value), path)
case JsError(e1) => B.reads(json) match {
case JsSuccess(value, path) => JsSuccess(Right(value), path)
case JsError(e2) => JsError(JsError.merge(e1, e2))
}
}
}
val json = Json.parse("""[
{
"id":2158488,
"name":"LIVE",
"screen_name":"live",
"is_closed":0,
"type":"page",
"photo_50":"https://pp.vk.me/c623416/v623416604/10e29/AUwb4GWpbD4.jpg",
"photo_100":"https://pp.vk.me/c623416/v623416604/10e28/DNSjabzHo70.jpg",
"photo_200":"https://pp.vk.me/c623416/v623416604/10e26/UAWL2PWZ_wM.jpg"
},
{
"id":11982368,
"name":"Forbes",
"screen_name":"forbes",
"is_closed":0,
"type":"page",
"photo_50":"https://pp.vk.me/c621326/v621326364/46b3/PE8CH3wuGSU.jpg",
"photo_100":"https://pp.vk.me/c621326/v621326364/46b2/_K_Pn8ayf08.jpg",
"photo_200":"https://pp.vk.me/c621326/v621326364/46b1/U58-5jSTiHI.jpg"
},
{
"type":"profile",
"id":123456,
"first_name":"John",
"last_name":"Doe"
}
]""")
case class Page(id: Int, name: String, screen_name: String, is_closed: Int, photo_50: String, photo_100: String, photo_200: String)
implicit val pageReads = Json.reads[Page]
case class Profile(id: Int, first_name: String, last_name: String)
implicit val profileReads = Json.reads[Profile]
def main(args: Array[String]): Unit = {
println(json.validate[Seq[Either[Profile, Page]]])
}
}
@graingert
Copy link

@graingert
Copy link

if you have ambiguous Either's then it will default to Left:

case class Foo(
foo: Either[Float, Int]
}
Foo(Right(1)) // BEWARE: round trips to Foo(Left(1.0))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment