Skip to content

Instantly share code, notes, and snippets.

@andimiller
Last active October 14, 2018 16:38
Show Gist options
  • Save andimiller/a2c9db501b20d6398abc0461659f309e to your computer and use it in GitHub Desktop.
Save andimiller/a2c9db501b20d6398abc0461659f309e to your computer and use it in GitHub Desktop.
object TypeSafeBuilder {
sealed trait BuilderStatus
object Satisfied extends BuilderStatus
object NotSatisfied extends BuilderStatus
case class Cat(name: String, age: Int)
object CatBuilder {
def apply() = new CatBuilder[NotSatisfied.type, NotSatisfied.type](None, None)
implicit class BuildableCatBuilder(cb: CatBuilder[Satisfied.type, Satisfied.type]) {
def build(): Cat = cb.hiddenBuild()
}
}
class CatBuilder[A <: BuilderStatus, B <: BuilderStatus] private (name: Option[String], age: Option[Int]) {
def withName(s: String) = new CatBuilder[Satisfied.type, B](Some(s), age)
def withAge(a: Int) = new CatBuilder[A, Satisfied.type ](name, Some(a))
private def hiddenBuild(): Cat = Cat(name.get, age.get)
}
CatBuilder().withAge(2).withName("Terry").build() // works
CatBuilder().withName("Bob").build() // doesn't compile
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment