Skip to content

Instantly share code, notes, and snippets.

@DanielGronau
Created October 30, 2021 11:29
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 DanielGronau/16db45567b7e0edf9ecad80d20707a6f to your computer and use it in GitHub Desktop.
Save DanielGronau/16db45567b7e0edf9ecad80d20707a6f to your computer and use it in GitHub Desktop.
Suggestion for Property DSL
import java.math.BigInteger
abstract class Constraint
abstract class Property {
abstract val required: Boolean
abstract val constraints: List<Constraint>
}
abstract class DocumentConstraint : Constraint()
data class DocumentProperty(
val children: Map<String, Property>,
override val required: Boolean,
override val constraints: List<DocumentConstraint>
) : Property()
abstract class IntConstraint : Constraint()
data class MaxIntConstraint(val max: BigInteger) : IntConstraint()
data class IntProperty(
override val required: Boolean,
override val constraints: List<IntConstraint>
) : Property()
abstract class ArrayConstraint : Constraint()
data class ArrayProperty(
val items: Property,
override val required: Boolean,
override val constraints: List<ArrayConstraint>
) : Property()
abstract class Builder<P : Property, C : Constraint> {
abstract fun build(): P
var required: Boolean = true
protected val constraints = mutableListOf<C>()
}
class DocumentBuilder : Builder<DocumentProperty, DocumentConstraint>() {
val children = mutableMapOf<String, Property>()
operator fun String.rangeTo(p: Property) {
if (children.containsKey(this)) {
throw IllegalArgumentException("Duplicate property name $this")
}
children[this] = p
}
override fun build() = DocumentProperty(children, required, constraints)
}
class IntBuilder : Builder<IntProperty, IntConstraint>() {
override fun build() = IntProperty(required, constraints)
fun maxInt(i: Int) {
constraints += MaxIntConstraint(i.toBigInteger())
}
fun maxInt(l: Long) {
constraints += MaxIntConstraint(l.toBigInteger())
}
fun maxInt(b: BigInteger) {
constraints += MaxIntConstraint(b)
}
}
class ArrayBuilder : Builder<ArrayProperty, ArrayConstraint>() {
var items: Property? = null
override fun build() = ArrayProperty(items!!, required, constraints)
}
fun document(block: DocumentBuilder.() -> Unit) = DocumentBuilder().also(block).build()
fun integer(block: IntBuilder.() -> Unit) = IntBuilder().also(block).build()
fun array(block: ArrayBuilder.() -> Unit) = ArrayBuilder().also(block).build()
fun main(args: Array<String>) {
val doc = document {
"key1"..integer {
maxInt(42L)
}
"key2"..integer {
required = false
}
"key3"..array {
items = integer { }
required = false
}
required = false
}
println(doc)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment