Skip to content

Instantly share code, notes, and snippets.

@carlpulley
Last active February 10, 2017 07:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save carlpulley/8464a2e1d5976d75e1cb0d1131115555 to your computer and use it in GitHub Desktop.
Save carlpulley/8464a2e1d5976d75e1cb0d1131115555 to your computer and use it in GitHub Desktop.
Validating Typesafe Configuration Files
package cakesolutions.example
import cakesolutions.config._
import scala.concurrent.duration.FiniteDuration
import scala.util.Try
import shapeless._
object InvariantConfig {
case object NameShouldBeNonEmptyAndLowerCase extends Exception
case object ShouldNotBeNegative extends Exception
sealed abstract case class HttpConfig(host: String, port: Int)
sealed abstract case class Settings(name: String, heartbeat: FiniteDuration, http: HttpConfig)
// Following allows Shapeless to create instances of our sealed abstract case classes
private implicit val genHttpConfig: Generic[HttpConfig] = new Generic[HttpConfig] {
type Repr = String :: Int :: HNil
def to(t: HttpConfig): Repr =
t.host :: t.port :: HNil
def from(r: Repr): HttpConfig =
new HttpConfig(r(0), r(1)) {}
}
private implicit val genSettings: Generic[Settings] = new Generic[Settings] {
type Repr = String :: FiniteDuration :: HttpConfig :: HNil
def to(t: Settings): Repr =
t.name :: t.heartbeat :: t.http :: HNil
def from(r: Repr): Settings =
new Settings(r(0), r(1), r(2)) {}
}
// The following code (due to the build implementation) may throw runtime class cast exceptions
def apply(): Try[Settings] = {
validateConfig("application.conf") { implicit config =>
build[Settings]((
validate[String]("name", NameShouldBeNonEmptyAndLowerCase)(_.matches("[a-z0-9_-]+")),
unchecked[FiniteDuration](required("http.heartbeat", "NOT_SET")),
via("http") { implicit config =>
build[HttpConfig]((
unchecked[String]("host"),
validate[Int]("port", ShouldNotBeNegative)(_ >= 0)
))
}
))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment