Created
May 12, 2016 15:19
-
-
Save davegurnell/f7c99ce7e921b7f23c5193a77d260be8 to your computer and use it in GitHub Desktop.
JsonWriter type class demo
This file contains hidden or 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
| // Scala script: run with "scala json.scala" | |
| // JSON Library --------------------------------- | |
| sealed trait JsValue { | |
| def stringify: String = this match { | |
| case JsNull => "null" | |
| case JsString(value) => "\"" + value + "\"" | |
| case JsNumber(value) => value.toString | |
| case JsBoolean(value) => value.toString | |
| case JsArray(values) => "[" + values.map(_.stringify).mkString(",") + "]" | |
| case JsObject(fields) => "{" + fields.map { case (k, v) => "\"" +k + "\":" + v.stringify + "\"" }.mkString(",") + "}" | |
| } | |
| } | |
| case object JsNull extends JsValue | |
| final case class JsString(value: String) extends JsValue | |
| final case class JsNumber(value: Double) extends JsValue | |
| final case class JsBoolean(value: Boolean) extends JsValue | |
| final case class JsArray(values: List[JsValue]) extends JsValue | |
| final case class JsObject(fields: List[(String, JsValue)]) extends JsValue | |
| trait JsonWriter[A] { | |
| def write(value: A): JsValue | |
| } | |
| object DefaultJsonWriters { | |
| implicit val stringWriter: JsonWriter[String] = | |
| new JsonWriter[String] { | |
| def write(value: String): JsValue = | |
| JsString(value) | |
| } | |
| implicit def listWriter[A](implicit valueWriter: JsonWriter[A]): JsonWriter[List[A]] = | |
| new JsonWriter[List[A]] { | |
| def write(values: List[A]): JsValue = | |
| JsArray(values.map(valueWriter.write)) | |
| } | |
| } | |
| object JsonSyntax { | |
| implicit class JsonOps[A](value: A) { | |
| def toJson(implicit writer: JsonWriter[A]): JsValue = | |
| writer.write(value) | |
| } | |
| } | |
| // Application ---------------------------------- | |
| case class Email(address: String) { | |
| def toJson: JsValue = | |
| JsString(address) | |
| } | |
| case class Person(name: String, email: Email) | |
| object AppJsonWriters { | |
| import JsonSyntax._ | |
| import DefaultJsonWriters._ | |
| implicit val emailWriter: JsonWriter[Email] = | |
| new JsonWriter[Email] { | |
| def write(email: Email): JsValue = | |
| email.address.toJson | |
| } | |
| implicit val personWriter: JsonWriter[Person] = | |
| new JsonWriter[Person] { | |
| def write(person: Person): JsValue = | |
| JsObject(List( | |
| "name" -> person.name.toJson, | |
| "email" -> person.email.toJson | |
| )) | |
| } | |
| } | |
| // Main ----------------------------------------- | |
| import JsonSyntax._ | |
| import DefaultJsonWriters._ | |
| import AppJsonWriters._ | |
| val dave = Person("Dave", Email("[email protected]")) | |
| val dave2 = Person("Dave2", Email("[email protected]")) | |
| val daves = List(dave, dave2) | |
| println(dave.toJson.stringify) | |
| println(dave.email.toJson.stringify) | |
| println(daves.toJson.stringify) | |
| println(List(daves, daves).toJson.stringify) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment