Skip to content

Commit

Permalink
encodeJson - encodes a JsonValue to JSON string
Browse files Browse the repository at this point in the history
  • Loading branch information
konnik committed Dec 19, 2023
1 parent c6b2d86 commit a6f4343
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
40 changes: 40 additions & 0 deletions lib/src/main/kotlin/konnik/json/encode/Encode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,46 @@ package konnik.json.encode

import konnik.json.JsonValue

/**
* Encodes a [JsonValue] as JSON string.
*/
fun encodeJson(json: JsonValue): String =
when (json) {
is JsonValue.Null -> "null"
is JsonValue.Bool -> if (json.value) "true" else "false"
is JsonValue.Num -> json.value.toString()
is JsonValue.Str -> "\"${escapeJsonString(json.value)}\""
is JsonValue.Array -> json.items.joinToString(
prefix = "[",
separator = ",",
postfix = "]",
transform = ::encodeJson
)

is JsonValue.Object -> json.members.entries.joinToString(
prefix = "{", separator = ",", postfix = "}"
) { (key, value) ->
"\"${escapeJsonString(key)}\":${encodeJson(value)}"
}
}

private fun escapeJsonString(value: String): String {
val sb = StringBuilder()
value.forEach {
when (it) {
'"' -> sb.append("\\$it")
'\\' -> sb.append("\\$it")
'\b' -> sb.append("\\b")
'\u000C' -> sb.append("\\f")
'\n' -> sb.append("\\n")
'\r' -> sb.append("\\r")
'\t' -> sb.append("\\t")
else -> sb.append(it)
}
}
return sb.toString()
}

// Basic functions for encoding native Kotlin types into JsonValue's.

/**
Expand Down
24 changes: 24 additions & 0 deletions lib/src/test/kotlin/konnik/json/encode/EncodeKtTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,28 @@ class EncodeKtTest {

assertEquals(expectedValue, myObj)
}

@Test
fun `encodeJson parseJson round trip`() {
val myObj = obj {
"a" to "Sausage"
"b" to 3.14E-99
"c" to -314
"d" to true
"e" to nullValue()
"f" to array("one", "two", "three")
"g" to obj {
"inner" to "JSON is fantastic!!!"
}
"h" to array(str("a string"), number(42), bool(false), nullValue())
"i" to "escaped\"\\\t\n\b\r\u000Cstring"
"j" to "unicode: ©\uD83E\uDD21"
}

val json = encodeJson(myObj)
val myObj2 = parseJson(json)

assertEquals(myObj, myObj2)

}
}

0 comments on commit a6f4343

Please sign in to comment.