Skip to content

Instantly share code, notes, and snippets.

@mpkocher
Last active May 14, 2016 06:12
Show Gist options
  • Save mpkocher/8d37114680b9c39d9adb119f74ce76e1 to your computer and use it in GitHub Desktop.
Save mpkocher/8d37114680b9c39d9adb119f74ce76e1 to your computer and use it in GitHub Desktop.
IdAble Example
import java.util.UUID
import spray.json._
import DefaultJsonProtocol._
/**
* Run using
*
* amm -f predef.scala Example.scala
*
*
*/
object Models {
sealed trait IdAble
case class IntIdAble(n: Int) extends IdAble
case class UUIDIdAble(n: UUID) extends IdAble
case class SimplePerson(name: String)
case class Person(i: IdAble, name: String)
}
object ModelImplicits {
import Models._
implicit def toUUIDIdAble(n: UUID): UUIDIdAble = UUIDIdAble(n)
implicit def toIntIdAble(n: Int):IntIdAble = IntIdAble(n)
}
trait CustomProtocol extends DefaultJsonProtocol {
import Models._
import ModelImplicits._
implicit object IdAbleFormat extends JsonFormat[IdAble] {
def write(i: IdAble): JsValue =
i match {
case IntIdAble(n) => JsNumber(n)
case UUIDIdAble(n) => JsString(n.toString)
}
def read(json: JsValue): IdAble = {
json match {
case JsString(n) => UUIDIdAble(UUID.fromString(n))
case JsNumber(n) => IntIdAble(n.toInt)
case _ => deserializationError("Expected IdAble Int or UUID format")
}
}
}
implicit val simplePersonFormat = jsonFormat1(SimplePerson)
implicit val personFormat = jsonFormat2(Person)
}
object CustomProtocol extends CustomProtocol
object RunExample {
import Models._
import CustomProtocol._
import ModelImplicits._
def run = {
def printer(x: JsValue): Unit = println(x.prettyPrint)
val s = SimplePerson("Ralph")
val sj = s.toJson
printer(sj)
val p1 = Person(1234, "Person A Int")
val p2 = Person(UUID.randomUUID(), "Person B UUID")
val people = Set(p1, p2)
people.foreach(x => printer(x.toJson))
// Round trip from Person -> Json -> String -> Json -> Person
val s1 = p1.toJson.toString
val px1 = s1.parseJson.convertTo[Person]
val px2 = p2.toJson.toString.parseJson.convertTo[Person]
println(px1)
println(px2)
}
}
//object Example extends App{
//
// RunExample.run
// println("Running Main.")
//}
// For Ammonite
import ammonite.ops._
// How do you get this to run without params ?
def main(name: String = "Ralph"): Unit = {
RunExample.run
}
import ammonite.ops._
import java.util.UUID
/**
Run with ammonite https://github.com/lihaoyi/Ammonite
`amm IdAbleExample.scala 1`
where 1 is the person id
**/
object Example {
sealed trait IdAble
case class UUIDIdAble(uuid: UUID) extends IdAble
case class IntIdAble(i: Int) extends IdAble
case class Person(name: String)
def getPersonByIdAble(i: IdAble): Person = {
i match {
case UUIDIdAble(uuid) => Person(s"Ralph ${uuid}")
case IntIdAble(i) => Person(s"Ralph ${i}")
}
}
implicit def toIntIdable(i: Int) = IntIdAble(i)
implicit def toUUIDIdAble(uuid: UUID) = UUIDIdAble(uuid)
def run(i: Int) = {
val uuid = UUID.randomUUID()
// Verbose
val ux = UUIDIdAble(uuid)
val ix = IntIdAble(i)
val p1 = getPersonByIdAble(ux)
val p2 = getPersonByIdAble(ix)
println(s"Got Person $p1")
println(s"Got Person $p2")
// This will use the implicits in the scope
// to do the conversion
val p3 = getPersonByIdAble(UUID.randomUUID())
val p4 = getPersonByIdAble(456)
println(s"Person $p3")
println(s"Person $p4")
}
}
def main(personId: Int) = {
Example.run(personId)
println("completed running example")
}
import ammonite.ops._
load.ivy("io.spray" %% "spray-json" % "1.3.2")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment