Created
October 30, 2021 11:29
-
-
Save DanielGronau/16db45567b7e0edf9ecad80d20707a6f to your computer and use it in GitHub Desktop.
Suggestion for Property DSL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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