Skip to content

Commit a6f4343

Browse files
committed
encodeJson - encodes a JsonValue to JSON string
1 parent c6b2d86 commit a6f4343

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

lib/src/main/kotlin/konnik/json/encode/Encode.kt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,46 @@ package konnik.json.encode
22

33
import konnik.json.JsonValue
44

5+
/**
6+
* Encodes a [JsonValue] as JSON string.
7+
*/
8+
fun encodeJson(json: JsonValue): String =
9+
when (json) {
10+
is JsonValue.Null -> "null"
11+
is JsonValue.Bool -> if (json.value) "true" else "false"
12+
is JsonValue.Num -> json.value.toString()
13+
is JsonValue.Str -> "\"${escapeJsonString(json.value)}\""
14+
is JsonValue.Array -> json.items.joinToString(
15+
prefix = "[",
16+
separator = ",",
17+
postfix = "]",
18+
transform = ::encodeJson
19+
)
20+
21+
is JsonValue.Object -> json.members.entries.joinToString(
22+
prefix = "{", separator = ",", postfix = "}"
23+
) { (key, value) ->
24+
"\"${escapeJsonString(key)}\":${encodeJson(value)}"
25+
}
26+
}
27+
28+
private fun escapeJsonString(value: String): String {
29+
val sb = StringBuilder()
30+
value.forEach {
31+
when (it) {
32+
'"' -> sb.append("\\$it")
33+
'\\' -> sb.append("\\$it")
34+
'\b' -> sb.append("\\b")
35+
'\u000C' -> sb.append("\\f")
36+
'\n' -> sb.append("\\n")
37+
'\r' -> sb.append("\\r")
38+
'\t' -> sb.append("\\t")
39+
else -> sb.append(it)
40+
}
41+
}
42+
return sb.toString()
43+
}
44+
545
// Basic functions for encoding native Kotlin types into JsonValue's.
646

747
/**

lib/src/test/kotlin/konnik/json/encode/EncodeKtTest.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,28 @@ class EncodeKtTest {
4040

4141
assertEquals(expectedValue, myObj)
4242
}
43+
44+
@Test
45+
fun `encodeJson parseJson round trip`() {
46+
val myObj = obj {
47+
"a" to "Sausage"
48+
"b" to 3.14E-99
49+
"c" to -314
50+
"d" to true
51+
"e" to nullValue()
52+
"f" to array("one", "two", "three")
53+
"g" to obj {
54+
"inner" to "JSON is fantastic!!!"
55+
}
56+
"h" to array(str("a string"), number(42), bool(false), nullValue())
57+
"i" to "escaped\"\\\t\n\b\r\u000Cstring"
58+
"j" to "unicode: ©\uD83E\uDD21"
59+
}
60+
61+
val json = encodeJson(myObj)
62+
val myObj2 = parseJson(json)
63+
64+
assertEquals(myObj, myObj2)
65+
66+
}
4367
}

0 commit comments

Comments
 (0)