androidx.compose.compiler.plugins.kotlin.JsonBuilder.kt Maven / Gradle / Ivy
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.compose.compiler.plugins.kotlin
import java.io.File
import java.io.OutputStreamWriter
import java.lang.Appendable
/**
* This class is a very rudimentary json serializer. It is not fully featured, and does not
* properly handle escaping strings, among other things. This is being used because the actual
* needs for json serialization we have are extremely minimal, and I don't want to introduce a
* library dependency unnecessarily, however if we start serializing more objects into JSON we
* should probably go down that path. Please use this class with caution.
*/
class JsonBuilder(private val sb: Appendable, private val indent: Int = 0) {
var hasEntry = false
private val nonWordCharRegex = Regex("\\W")
private fun entryLiteral(key: String, value: String) {
with(sb) {
if (hasEntry) {
appendLine(",")
}
append(" ".repeat(indent))
append("\"${key.replace(nonWordCharRegex, "")}\"")
append(": ")
append(value)
}
hasEntry = true
}
fun entry(key: String, value: Int) = entryLiteral(key, "$value")
fun entry(key: String, fn: JsonBuilder.() -> Unit) = entryLiteral(
key,
buildString { JsonBuilder(this, indent + 1).with(fn) }
)
fun with(fn: JsonBuilder.() -> Unit) {
with(sb) {
appendLine("{")
fn()
if (hasEntry) appendLine()
append("}")
}
}
}
fun Appendable.appendJson(fn: JsonBuilder.() -> Unit) {
JsonBuilder(this, 1).with(fn)
}
class CsvBuilder(private val writer: Appendable) {
fun row(fn: CsvBuilder.() -> Unit): Unit = with(writer) {
fn()
appendLine()
}
fun col(value: String): Unit = with(writer) {
require(!value.contains(',')) { "Illegal character ',' found: $value" }
append(value)
append(",")
}
fun col(value: Int): Unit = with(writer) {
append("$value")
append(",")
}
fun col(value: Boolean): Unit = with(writer) {
append(if (value) "1" else "0")
append(",")
}
}
fun File.write(fn: OutputStreamWriter.() -> Unit) {
if (!exists()) {
parentFile.mkdirs()
createNewFile()
}
writer().use {
it.fn()
}
}
fun Appendable.appendCsv(fn: CsvBuilder.() -> Unit) {
CsvBuilder(this).fn()
}