Load Dhall config directly into Scala case class
libraryDependencies += "us.oyanglul" %% "dhall-generic" % "0.3.+"
There is a dhall config
let Shape = <Rectangle: {width: Double, height: Double}| Circle: {radius: Double}>
in Shape.Circle {radius = 1.2}
And you can parse them into dhall Expr
import org.dhallj.syntax._
val expr = """
let Shape = <Rectangle: {width: Double, height: Double}| Circle: {radius: Double}>
in Shape.Circle {radius = 1.2}
""".parseExpr
Supposed that you have some Scala case classes
enum Shape:
case Rectangle(width: Double, height: Double)
case Circle(radius: Double)
to load a dhall expr into Scala case classes, simply just
derives Decoder
import us.oyanglul.dhall.generic.Decoder
enum Shape derives Decoder: // derive will generate decoder inline
case Rectangle(width: Double, height: Double)
case Circle(radius: Double)
as[Shape]
import us.oyanglul.dhall.generic.as
expr.normalize.as[Shape]
// => Right(Circle(1.2)): Either[DecodingFailure, Shape]
Supposed that you have some Scala case classes
sealed trait Shape
object Shape {
case class Rectangle(width: Double, height: Double) extends Shape
case class Circle(radius: Double) extends Shape
}
to load a dhall expr into Scala case classes, simply just
import org.dhallj.codec.syntax._ // for `.as[A]` syntax
import org.dhallj.codec.Decoder._ // Decoders for primity types
import us.oyanglul.dhall.generic._ // generate generic decoders
expr.normalize.as[Shape]
// => Right(Circle(1.2)): Either[DecodingFailure, Shape]
It is very simple to replace HOCON application.conf
with dhall.
To load src/main/resources/application.dhall
from classpath your will need dhall-imports
import org.dhallj.syntax._
import org.dhallj.codec.syntax._
import us.oyanglul.dhall.generic._
import org.dhallj.imports.syntax._
BlazeClientBuilder[IO](ExecutionContext.global).resource.use { implicit c =>
IO.fromEither("classpath:/application.dhall".parseExpr)
.flatMap(_.resolveImports[IO])
.flatMap{expr => IO.fromEither(expr.normalize.as[Config])}
}
This project itself is an example of how to load dhall into build.sbt
It is recursively using previous version to load ./build.dhall to libraryDependencies
libraryDependencies ++= dhall.load.modules.map{case Module(o, n, v) => o %% n % v},
Create new decoder from existing decoder
i.e. UUID
given (using d: Decoder[String]): Decoder[UUID] = d.map(UUID.fromString)
implicit val decodeUUID: Decoder[UUID] = decodeString.map(UUID.from)