Skip to content

Instantly share code, notes, and snippets.

@code-twister
Last active April 12, 2019 14:14
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 code-twister/1e159380fa910298edd8012a394dfb08 to your computer and use it in GitHub Desktop.
Save code-twister/1e159380fa910298edd8012a394dfb08 to your computer and use it in GitHub Desktop.
Kotlin DSL example
class Village(val name: String, val huts: MutableList<Hut>)
class Hut(val address: String,
val vikings: MutableList<Viking>,
val dragons: MutableList<Dragon>)
class Viking(val name: String)
class Dragon(val name: String)
// Main.kt
val berk = village(name = "Berk") { // <- VillageBuilder
hut(address = "13 Wings Avenue") { // <- HutBuilder
viking("Bjorn")
dragon("Toothless")
dragon("Gruff")
dragon("Cloud Jumper")
hut { /* <- we shouldn't be able to */ }
}
hut {
address = "8 Ball St"
viking("Ragnar")
viking("Helga")
dragon("Scrill")
}
}
@DragonDSL
class VillageBuilder(/* ... */)
@DragonDSL
class HutBuilder(/* ... */)
@DslMarker
annotation class DragonDSL
// Main.kt
val berk = village(name = "Berk") { // <- VillageBuilder
hut(address = "13 Wings Avenue") { // <- HutBuilder
viking("Bjorn")
dragon("Toothless")
dragon("Gruff")
dragon("Cloud Jumper")
this@village.hut { /* <- we can do it but only with explicit receiver */ }
}
hut {
address = "8 Ball St"
viking("Ragnar")
viking("Helga")
dragon("Scrill")
}
}
package dragons
// DragonDSL.kt
fun village(name: String, init: VillageBuilder.() -> Unit): Village {
return VillageBuilder(name).apply(init).build()
}
@DragonDSL
class VillageBuilder(private val name: String) {
private val huts = mutableListOf<Hut>()
fun build() = Village(name, huts)
fun hut(address: String = "", init: HutBuilder.() -> Unit) {
huts.add(HutBuilder(address).apply(init).build())
}
}
@DragonDSL
class HutBuilder(var address: String = "") {
private val vikings = mutableListOf<Viking>()
private val dragons = mutableListOf<Dragon>()
fun build(): Hut = Hut(address, vikings, dragons)
fun viking(name: String) {
vikings.add(Viking(name))
}
fun vikings(vararg names: String) {
vikings.addAll(names.map { Viking(it) })
}
fun dragon(name: String) {
dragons.add(Dragon(name))
}
fun dragons(vararg names: String) {
dragons.addAll(names.map { Dragon(it) })
}
}
@DslMarker
annotation class DragonDSL
// Main.kt
val berk = village(name = "Berk") { // <- VillageBuilder
hut(address = "13 Wings Avenue") { // <- HutBuilder
viking("Bjorn")
dragons("Toothless", "Gruff", "Cloud Jumper")
}
hut {
address = "8 Ball St"
vikings("Ragnar", "Helga")
dragon("Scrill")
}
}
// DragonDSL.kt
fun village(init: VillageBuilder.() -> Unit): Village {
return VillageBuilder().apply(init).build()
}
class VillageBuilder {
fun build(): Village {
TODO("not implemented")
}
}
// Main.kt
val berk = village { // <- VillageBuilder
}
// DragonDSL.kt
fun village(init: VillageBuilder.() -> Unit): Village {
return VillageBuilder().apply(init).build()
}
class VillageBuilder {
private val huts = mutableListOf<Hut>()
fun build(): Village {
TODO("not implemented")
}
fun hut(init: HutBuilder.() -> Unit) {
huts.add(HutBuilder().apply(init).build())
}
}
class HutBuilder {
fun build(): Hut {
TODO("not implemented")
}
}
// Main.kt
val berk = village { // <- VillageBuilder
hut { // <- HutBuilder
}
}
// DragonDSL.kt
fun village(name: String, init: VillageBuilder.() -> Unit): Village {
return VillageBuilder(name).apply(init).build()
}
class VillageBuilder(private val name: String) {
private val huts = mutableListOf<Hut>()
fun build() = Village(name, huts)
fun hut(init: HutBuilder.() -> Unit) {
huts.add(HutBuilder().apply(init).build())
}
}
class HutBuilder {
fun build(): Hut {
TODO("not implemented")
}
}
// Main.kt
val berk = village(name = "Berk") { // <- VillageBuilder
hut { // <- HutBuilder
}
}
// DragonDSL.kt
fun village(name: String, init: VillageBuilder.() -> Unit): Village {
return VillageBuilder(name).apply(init).build()
}
class VillageBuilder(private val name: String) {
private val huts = mutableListOf<Hut>()
fun build() = Village(name, huts)
fun hut(init: HutBuilder.() -> Unit) {
huts.add(HutBuilder().apply(init).build())
}
}
class HutBuilder {
private val vikings = mutableListOf<Viking>()
private val dragons = mutableListOf<Dragon>()
fun build(): Hut = Hut("", vikings, dragons)
fun viking(name: String) {
vikings.add(Viking(name))
}
fun dragon(name: String) {
dragons.add(Dragon(name))
}
}
// Main.kt
val berk = village(name = "Berk") { // <- VillageBuilder
hut { // <- HutBuilder
viking("Bjorn")
dragon("Toothless")
dragon("Gruff")
dragon("Cloud Jumper")
}
hut {
viking("Ragnar")
viking("Helga")
dragon("Scrill")
}
}
// DragonDSL.kt
fun village(name: String, init: VillageBuilder.() -> Unit): Village {
return VillageBuilder(name).apply(init).build()
}
class VillageBuilder(private val name: String) {
private val huts = mutableListOf<Hut>()
fun build() = Village(name, huts)
fun hut(address: String = "", init: HutBuilder.() -> Unit) {
huts.add(HutBuilder(address).apply(init).build())
}
}
class HutBuilder(var address: String = "") {
private val vikings = mutableListOf<Viking>()
private val dragons = mutableListOf<Dragon>()
fun build(): Hut = Hut(address, vikings, dragons)
fun viking(name: String) {
vikings.add(Viking(name))
}
fun dragon(name: String) {
dragons.add(Dragon(name))
}
}
// Main.kt
val berk = village(name = "Berk") { // <- VillageBuilder
hut(address = "13 Wings Avenue") { // <- HutBuilder
viking("Bjorn")
dragon("Toothless")
dragon("Gruff")
dragon("Cloud Jumper")
}
hut {
address = "8 Ball St"
viking("Ragnar")
viking("Helga")
dragon("Scrill")
}
}
val vikings1 = mutableListOf(Viking("Bjorn"))
val vikings2 = mutableListOf(Viking("Ragnar"), Viking("Helga"))
val dragons1 = mutableListOf(
Dragon("Toothless"),
Dragon("Gruff"),
Dragon("Cloudjumper"))
val dragons2 = mutableListOf(Dragon("Scrill"))
val huts = mutableListOf(
Hut("13 Wings Avenue", vikings1, dragons1),
Hut("8 Ball St", vikings2, dragons2)
)
val firstVillage = Village("Berk", huts)
val secondVillage = Village("Berk",
mutableListOf(
Hut("13 Wings Avenue",
mutableListOf(Viking("Bjorn")),
mutableListOf(
Dragon("Toothless"),
Dragon("Gruff"),
Dragon("Cloudjumper"))
),
Hut("8 Ball St",
mutableListOf(Viking("Ragnar"), Viking("Helga")),
mutableListOf(Dragon("Scrill")))
)
)
class Foo {
fun test() {
println("testing bar!")
}
}
fun fooCreator(): Foo {
return Foo()
}
fun higherOrderFun(functionRef: () -> Foo) {
functionRef().test()
}
fun main(args: Array<String>) {
higherOrderFun(::fooCreator)
higherOrderFun({ Foo() })
higherOrderFun { Foo() }
}
class Foo(val message: String) {
fun test() {
println(message)
}
}
fun fooCreator(message: String): Foo {
return Foo(message)
}
fun higherOrderFun(functionRef: (String) -> Foo) {
functionRef("From fun").test()
}
fun main(args: Array<String>) {
higherOrderFun(::fooCreator)
higherOrderFun { Foo("From main") }
}
class Foo(val message: String)
fun Foo.test() {
println(message)
}
fun higherOrderFun(foo: Foo, functionRef: Foo.() -> Unit) {
foo.functionRef()
}
fun main(args: Array<String>) {
higherOrderFun(Foo("From main"), Foo::test)
higherOrderFun(Foo("Another example"), { println("Custom: ${message}") })
higherOrderFun(Foo("Another example")) {
println("Custom: $message")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment