Skip to content

Instantly share code, notes, and snippets.

@jnorthrup
Forked from mpetuska/JSObj.kt
Last active October 15, 2021 03:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jnorthrup/51f2b23bde522bb03d74aa552c295f6b to your computer and use it in GitHub Desktop.
Save jnorthrup/51f2b23bde522bb03d74aa552c295f6b 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?> = linkedMapOf()) : MutableMap<String, Any?> by map {
object Arr {
@JSBuilderDsl
operator fun get(vararg items: Any?) = items
}
@JSBuilderDsl
val arr = Arr
/**
* set primitive
*/
infix operator fun String.rem(value: Any?) = this `⁚` value //two escaped dots if inlined
@JSSetterDsl
/**
* set primitive
*/
infix fun String.`⁚`(t: Any?) {
map[this] = t
}
/**
* 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 `{}` get() = JSObj()
fun main() {
val myJsObject = obj {
"boolean" % true
"number" % 1
"string" % "str"
"null" % null
"array"[
1,
"str",
null,
`{}`,
arr[1, "2", null, 3]
]
"object" {
"boolean" % true
"number" % 1
"string" % "str"
"null" `⁚` null
"array"[1, "str", null]
}
}
System.err.println(myJsObject)//put breakpoint here.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment