Kotlin DSL for creating json objects (without creating garbage)
Do you need a DSL? You lose the ability to enforce String
keys, but vanilla Kotlin isn't that bad :)
JSONObject(mapOf(
"name" to "ilkin",
"age" to 37,
"male" to true,
"contact" to mapOf(
"city" to "istanbul",
"email" to "[email protected]"
)
))
You can use a Deque as a stack to track your current JSONObject
context with a single JsonObjectBuilder
:
fun json(build: JsonObjectBuilder.() -> Unit): JSONObject {
return JsonObjectBuilder().json(build)
}
class JsonObjectBuilder {
private val deque: Deque<JSONObject> = ArrayDeque()
fun json(build: JsonObjectBuilder.() -> Unit): JSONObject {
deque.push(JSONObject())
this.build()
return deque.pop()
}
infix fun <T> String.To(value: T) {
deque.peek().put(this, value)
}
}
fun main(args: Array<String>) {
val jsonObject =
json {
"name" To "ilkin"
"age" To 37
"male" To true
"contact" To json {
"city" To "istanbul"
"email" To "[email protected]"
}
}
println(jsonObject)
}
Example output:
{"contact":{"city":"istanbul","email":"[email protected]"},"name":"ilkin","age":37,"male":true}
Calling json
and build
across multiple threads on a single JsonObjectBuilder
would be problematic but that shouldn't be a problem for your use case.