Skip to content

Instantly share code, notes, and snippets.

@davegurnell
Created May 12, 2016 15:19
Show Gist options
  • Select an option

  • Save davegurnell/f7c99ce7e921b7f23c5193a77d260be8 to your computer and use it in GitHub Desktop.

Select an option

Save davegurnell/f7c99ce7e921b7f23c5193a77d260be8 to your computer and use it in GitHub Desktop.
JsonWriter type class demo
// 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