
commonMain.ch.softappeal.yass2.Dumper.kt Maven / Gradle / Ivy
package ch.softappeal.yass2
import kotlin.reflect.*
public typealias DumperProperties = (type: KClass<*>) -> List>
/** Writes value (without line breaks) if responsible else does nothing. */
public typealias BaseDumper = StringBuilder.(value: Any) -> Unit
public typealias Dumper = StringBuilder.(value: Any?) -> StringBuilder
/**
* Supports the following types out-of-the-box:
* `null`, [Boolean], [Number], [CharSequence], [List] and classes with its properties.
*/
public fun dumper(properties: DumperProperties, baseDumper: BaseDumper): Dumper = { value ->
val object2reference = HashMap(16)
var indent = 0
fun dump(value: Any?) {
fun appendIndent() {
append(" ".repeat(indent))
}
fun inc(s: CharSequence) {
append(s)
appendLine()
indent++
}
fun dec(s: CharSequence) {
indent--
appendIndent()
append(s)
}
fun dumpList(list: List<*>) {
inc("[")
for (element in list) {
appendIndent()
dump(element)
appendLine()
}
dec("]")
}
fun dumpObject(obj: Any) {
val reference = object2reference[obj]
if (reference != null) {
append("#$reference")
return
}
val index = object2reference.size
object2reference[obj] = index
val type = obj::class
inc("${type.simpleName}(")
for (property in properties(type)) property.get(obj)?.let { propertyValue ->
appendIndent()
append("${property.name} = ")
dump(propertyValue)
appendLine()
}
dec(")#$index")
}
when (value) {
null -> append("null")
is Boolean -> append(value)
is Number -> append(value)
is CharSequence -> append("\"$value\"")
is List<*> -> dumpList(value)
else -> {
val oldLength = length
baseDumper(value)
if (oldLength == length) dumpObject(value)
}
}
}
dump(value)
this
}
public fun dumperProperties(vararg mappings: Pair, List>>): DumperProperties {
val map = mapOf(*mappings)
return { type -> map[type] ?: error("missing mapping for '$type'") }
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy