Last active
July 14, 2018 12:10
-
-
Save netzwerg/521c066f52a0adb0e95b4af9538985d5 to your computer and use it in GitHub Desktop.
Parsing heterogeneous JSON with Circe
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
package ch.netzwerg | |
import cats.data.Xor | |
import io.circe._ | |
import io.circe.generic.auto._ | |
import io.circe.parser._ | |
import org.scalajs.dom.document | |
import scala.scalajs.js | |
object App extends js.JSApp { | |
case class Demo(variables: Seq[Variable]) | |
case class Variable(name: String, `type`: String, value: VariableValue) | |
sealed trait VariableValue | |
case class StringVariableValue(value: String) extends VariableValue | |
case class LongVariableValue(value: Long) extends VariableValue | |
case class BooleanVariableValue(value: Boolean) extends VariableValue | |
object Variable { | |
implicit val decodeVariable: Decoder[Variable] = Decoder.instance(c => { | |
val `type` = c.downField("type").as[String] | |
val variableValueField = c.downField("value") | |
val variableValue = `type`.flatMap { | |
case "string" => variableValueField.as[String].map(StringVariableValue) | |
case "long" => variableValueField.as[Long].map(LongVariableValue) | |
case "boolean" => variableValueField.as[Boolean].map(BooleanVariableValue) | |
} | |
for { | |
name <- c.downField("name").as[String] | |
t <- `type` | |
vv <- variableValue | |
} yield Variable(name, t, vv) | |
} | |
) | |
} | |
@scala.scalajs.js.annotation.JSExport | |
override def main(): Unit = { | |
val json = | |
"""{ | |
"variables": [ | |
{ | |
"name": "one", | |
"type": "string", | |
"value": "kermit" | |
}, | |
{ | |
"name": "two", | |
"type": "long", | |
"value": 42 | |
}, | |
{ | |
"name": "three", | |
"type": "boolean", | |
"value": true | |
} | |
] | |
}""" | |
val errorOrResult = decode[Demo](json) | |
val out = document.getElementById("root") | |
errorOrResult match { | |
case Xor.Right(result) => out.innerHTML = "Result: " + result | |
case Xor.Left(error) => out.innerHTML = "Error: " + error | |
} | |
} | |
} |
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
val root = Project(id = "demo", base = file(".")) | |
.enablePlugins(ScalaJSPlugin) | |
.settings( | |
version := "0.1-SNAPSHOT", | |
scalaVersion := "2.11.8", | |
persistLauncher in Compile := true, | |
libraryDependencies ++= Seq( | |
"org.scala-js" %%% "scalajs-dom" % "0.9.1", | |
"io.circe" %%% "circe-scalajs" % "0.5.0-M2", | |
"io.circe" %%% "circe-parser" % "0.5.0-M2", | |
"io.circe" %%% "circe-generic" % "0.5.0-M2" | |
) | |
) |
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Demo</title> | |
</head> | |
<body> | |
<div id="root"> | |
<!-- Dynamic content --> | |
</div> | |
<!-- Include JavaScript dependencies --> | |
<script type="text/javascript" src="./target/scala-2.11/demo-jsdeps.js"></script> | |
<!-- Include Scala.js compiled code --> | |
<script type="text/javascript" src="./target/scala-2.11/demo-fastopt.js"></script> | |
<!-- Run JSApp --> | |
<script type="text/javascript" src="./target/scala-2.11/demo-launcher.js"></script> | |
</body> | |
</html> |
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
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.10") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment