I need some hints to write a scala program that could read json file and create a case class at run time. As an example if we have json class like -
Employ{
name:{datatype:String, null:false}
age:{datatype:Int, null:true}
Address:{city: {datatype: String, null:true}, zip: {datatype: String, null:false}}
}
and this should create class like
case class Employ(name: String, age: Option[Int], address: Address}
case class Address(city: Option[String], zip:String}
would it be possible to do it in scala?
Yes, you can easily achieve this using TreeHugger. I did a similar thing for one of my work projects.
Below is a toy example which produces a Scala Akka Actor class. It needs to be cleaned up but, hopefully, you get the idea:
import argonaut.Argonaut._
import argonaut._
import org.scalatest.FunSuite
import treehugger.forest._
import definitions._
import treehuggerDSL._
class ConvertJSONToScalaSpec extends FunSuite {
test("read json") {
val input =
"""
|{
| "rulename" : "Rule 1",
| "condition" : [
| {
| "attribute" : "country",
| "operator" : "eq",
| "value" : "DE"
| }
| ],
| "consequence" : "route 1"
|}
""".stripMargin
val updatedJson: Option[Json] = input.parseOption
val tree =
BLOCK(
IMPORT(sym.actorImports),
CLASSDEF(sym.c).withParents(sym.d, sym.e) :=
BLOCK(
IMPORT(sym.consignorImport, "_"),
DEFINFER(sym.methodName) withFlags (Flags.OVERRIDE) := BLOCK(
CASE(sym.f DOT sym.methodCall APPLY (REF(sym.mc))) ==>
BLOCK(
sym.log DOT sym.logmethod APPLY (LIT(sym.logmessage)),
(IF (sym.declaration DOT sym.header DOT sym.consignor DOT sym.consignoreTID ANY_== LIT(1))
THEN (sym.sender APPLY() INFIX ("!", LIT(sym.okcm)))
ELSE
(sym.sender APPLY() INFIX ("!", LIT(sym.badcm)))
)
)
)
)
) inPackage (sym.packageName)
}
Essentially all you need to do is work out how to use the TreeHugger macros; each macro represents a specific keyword in Scala. It gives you a type-safe way to do your meta-programming.
There's also Scala Meta but I haven't used that.