A small study on DSL design for map declarations.
- Instant execution compatibility
- Flexible wiring of keys, values and maps
- Familiar syntax
-
Use a MapProperty, see Extension.placeholders
interface Extension { val placeholders: MapProperty<String, Any> }
-
Add Kotlin operator extensions as needed, see kotlin-dsl/build.gradle.kts
/** * Enables the `map[key] = value` syntax on [MapProperty] values. */ operator fun <K, V> MapProperty<K, V>.set(k: K, v: V) = put(k, v) /** * Enables the `map("k1" to "v1", "kn" to "vn")` syntax on [MapProperty] values. */ operator fun <K, V> MapProperty<K, V>.invoke(vararg entries: Pair<K, V>) = entries.forEach { (k, v) -> this@invoke.put(k, v) }
Resulting in the following Kotlin DSL configuration syntax:
my {
placeholders["foo"] = "bar"
placeholders(
"a" to "b",
"c" to "d",
"key" to true
)
}
And the following Groovy DSL configuration syntax:
my {
placeholders = [a: 'b', c: 'd']
placeholders.e = 'f'
placeholders['g'] = 'h'
// Can be achieved via custom method OR Groovy decoration
// placeholders i: 'j', k: 'l'
}