Skip to content

Instantly share code, notes, and snippets.

@mpetuska
Created October 14, 2021 10:49
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mpetuska/40f716142c9a10450074d3c4afff1e38 to your computer and use it in GitHub Desktop.
Save mpetuska/40f716142c9a10450074d3c4afff1e38 to your computer and use it in GitHub Desktop.
Fluent Kotlin DSL for building JSON trees
@DslMarker
annotation class JSBuilderDsl
@DslMarker
annotation class JSSetterDsl
data class JSObj(val map: MutableMap<String, Any?> = mutableMapOf()) : MutableMap<String, Any?> by map {
object Arr {
@JSBuilderDsl
operator fun get(vararg items: Any?) = items
}
@JSBuilderDsl
val arr = Arr
/**
* set primitive
*/
@JSSetterDsl
infix fun String.by(value: Any?) {
map[this] = value
}
/**
* set object
*/
@JSSetterDsl
operator fun String.invoke(block: JSObj.() -> Unit) {
map[this] = JSObj().apply(block)
}
/**
* set array
*/
@JSSetterDsl
operator fun String.get(vararg items: Any?) {
map[this] = items
}
}
typealias JSArr<T> = Array<T>
/**
* build array
*/
@JSBuilderDsl
fun <T> arr(vararg items: T): JSArr<out T> = items
/**
* build object
*/
@JSBuilderDsl
fun obj(block: JSObj.() -> Unit): JSObj = JSObj().apply(block)
val myJsObject: JSObj = obj {
"boolean" by true
"number" by 1
"string" by "str"
"null" by null
"array"[
1,
"str",
null,
obj {
},
arr[1, "2", null, 3]
]
"object" {
"boolean" by true
"number" by 1
"string" by "str"
"null" by null
"array"[1, "str", null]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment