@@ -25,6 +25,13 @@ package at.syntaxerror.json5
25
25
26
26
import kotlinx.serialization.json.JsonArray
27
27
import kotlinx.serialization.json.JsonObject
28
+ import kotlinx.serialization.json.JsonPrimitive
29
+ import kotlinx.serialization.json.booleanOrNull
30
+ import kotlinx.serialization.json.contentOrNull
31
+ import kotlinx.serialization.json.doubleOrNull
32
+ import kotlinx.serialization.json.floatOrNull
33
+ import kotlinx.serialization.json.intOrNull
34
+ import kotlinx.serialization.json.longOrNull
28
35
29
36
/* *
30
37
* A utility class for serializing [JSONObjects][DecodeJson5Object] and [JSONArrays][DecodeJson5Array]
@@ -36,9 +43,10 @@ class JSONStringify(
36
43
private val options : JSONOptions
37
44
) {
38
45
39
- private val quoteToken = if (options.quoteSingle) ' \' ' else ' "'
40
- private val emptyString = " $quoteToken$quoteToken "
41
- private val indentFactor = options.indentFactor
46
+ private val quoteToken: Char get() = if (options.quoteSingle) ' \' ' else ' "'
47
+ private val emptyString: String get() = " $quoteToken$quoteToken "
48
+ private val indentFactor: UInt get() = options.indentFactor
49
+ private val isIndented: Boolean get() = indentFactor > 0u
42
50
43
51
/* *
44
52
* Converts a JSONObject into its string representation. The indentation factor enables
@@ -47,7 +55,8 @@ class JSONStringify(
47
55
* characters.
48
56
*
49
57
* `indentFactor = 2`:
50
- * ```
58
+ *
59
+ * ```json
51
60
* {
52
61
* "key0": "value0",
53
62
* "key1": {
@@ -59,7 +68,7 @@ class JSONStringify(
59
68
*
60
69
* `indentFactor = 0`:
61
70
*
62
- * ```
71
+ * ```json
63
72
* {"key0":"value0","key1":{"nested":123},"key2":false}
64
73
* ```
65
74
*/
@@ -68,7 +77,6 @@ class JSONStringify(
68
77
indent : String = "",
69
78
): String {
70
79
val childIndent = indent + " " .repeat(indentFactor.toInt())
71
- val isIndented = indentFactor > 0u
72
80
73
81
val sb = StringBuilder ()
74
82
sb.append(' {' )
@@ -99,7 +107,8 @@ class JSONStringify(
99
107
*
100
108
*
101
109
* `indentFactor = 2`:
102
- * ```
110
+ *
111
+ * ```json
103
112
* [
104
113
* "value",
105
114
* {
@@ -110,7 +119,8 @@ class JSONStringify(
110
119
* ```
111
120
*
112
121
* `indentFactor = 0`:
113
- * ```
122
+ *
123
+ * ```json
114
124
* ["value",{"nested":123},false]
115
125
* ```
116
126
*/
@@ -119,7 +129,6 @@ class JSONStringify(
119
129
indent : String = "",
120
130
): String {
121
131
val childIndent = indent + " " .repeat(indentFactor.toInt())
122
- val isIndented = indentFactor > 0u
123
132
124
133
val sb = StringBuilder ()
125
134
sb.append(' [' )
@@ -144,18 +153,21 @@ class JSONStringify(
144
153
indent : String ,
145
154
): String {
146
155
return when (value) {
147
- null -> " null"
148
- is JsonObject -> encodeObject(value, indent)
149
- is JsonArray -> encodeArray(value, indent)
150
- is String -> escapeString(value)
151
- is Double -> {
156
+ null -> " null"
157
+
158
+ is JsonObject -> encodeObject(value, indent)
159
+ is JsonArray -> encodeArray(value, indent)
160
+ is JsonPrimitive -> encode(value.anyOrNull, indent)
161
+
162
+ is String -> escapeString(value)
163
+ is Double -> {
152
164
when {
153
165
! options.allowNaN && value.isNaN() -> throw JSONException (" Illegal NaN in JSON" )
154
166
! options.allowInfinity && value.isInfinite() -> throw JSONException (" Illegal Infinity in JSON" )
155
167
else -> value.toString()
156
168
}
157
169
}
158
- else -> value.toString()
170
+ else -> value.toString()
159
171
}
160
172
}
161
173
@@ -172,6 +184,7 @@ class JSONStringify(
172
184
) { c: Char ->
173
185
174
186
val formattedChar: String? = when (c) {
187
+ in listOf (' \' ' , ' \" ' ) -> if (c == quoteToken) " \\ $quoteToken " else " $c "
175
188
quoteToken -> " \\ $quoteToken "
176
189
in Json5EscapeSequence .escapableChars -> Json5EscapeSequence .asEscapedString(c)
177
190
else -> when (c.category) {
@@ -181,12 +194,22 @@ class JSONStringify(
181
194
CharCategory .CONTROL ,
182
195
CharCategory .PRIVATE_USE ,
183
196
CharCategory .SURROGATE ,
184
- CharCategory .UNASSIGNED -> String .format(" \\ u%04X" , c)
197
+ CharCategory .UNASSIGNED -> String .format(" \\ u%04X" , c.code )
185
198
else -> null
186
199
}
187
200
}
188
201
formattedChar ? : c.toString()
189
202
}
190
203
}
191
204
}
205
+
206
+ companion object {
207
+ private val JsonPrimitive .anyOrNull: Any?
208
+ get() = intOrNull
209
+ ? : longOrNull
210
+ ? : doubleOrNull
211
+ ? : floatOrNull
212
+ ? : booleanOrNull
213
+ ? : contentOrNull
214
+ }
192
215
}
0 commit comments