ProgressEvent.kt
package com.depanalyzer.cli
import java.time.Instant
data class ProgressEvent(
val type: String,
val message: String,
val phase: String? = null,
val current: Int? = null,
val total: Int? = null,
val timestamp: Instant = Instant.now()
)
internal object ProgressEventJsonWriter {
fun write(event: ProgressEvent): String {
val fields = mutableListOf(
"\"stream\":\"depanalyzer-progress\"",
"\"type\":\"${escape(event.type)}\"",
"\"message\":\"${escape(event.message)}\"",
"\"timestamp\":\"${event.timestamp}\""
)
event.phase?.let { fields += "\"phase\":\"${escape(it)}\"" }
event.current?.let { fields += "\"current\":$it" }
event.total?.let { fields += "\"total\":$it" }
return "{${fields.joinToString(",")}}"
}
private fun escape(value: String): String = buildString {
value.forEach { char ->
when (char) {
'\\' -> append("\\\\")
'"' -> append("\\\"")
'\n' -> append("\\n")
'\r' -> append("\\r")
'\t' -> append("\\t")
else -> if (char.code < 0x20) append("\\u${char.code.toString(16).padStart(4, '0')}") else append(char)
}
}
}
}