-
Notifications
You must be signed in to change notification settings - Fork 618
/
MetaSerializableJsonTest.kt
71 lines (59 loc) · 2.5 KB
/
MetaSerializableJsonTest.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package kotlinx.serialization.features
import kotlinx.serialization.*
import kotlinx.serialization.json.*
import kotlin.test.*
class MetaSerializableJsonTest : JsonTestBase() {
@MetaSerializable
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS)
annotation class JsonComment(val comment: String)
@JsonComment("class_comment")
data class IntDataCommented(val i: Int)
@Serializable
data class Carrier(
val plain: String,
@JsonComment("string_comment") val commented: StringData,
val intData: IntDataCommented
)
class CarrierSerializer : JsonTransformingSerializer<Carrier>(serializer()) {
private val desc = Carrier.serializer().descriptor
private fun List<Annotation>.comment(): String? = filterIsInstance<JsonComment>().firstOrNull()?.comment
private val commentMap = (0 until desc.elementsCount).associateBy({ desc.getElementName(it) },
{ desc.getElementAnnotations(it).comment() ?: desc.getElementDescriptor(it).annotations.comment() })
// NB: we may want to add this to public API
private fun JsonElement.editObject(action: (MutableMap<String, JsonElement>) -> Unit): JsonElement {
val mutable = this.jsonObject.toMutableMap()
action(mutable)
return JsonObject(mutable)
}
override fun transformDeserialize(element: JsonElement): JsonElement {
return element.editObject { result ->
for ((key, value) in result) {
commentMap[key]?.let {
result[key] = value.editObject {
it.remove("comment")
}
}
}
}
}
override fun transformSerialize(element: JsonElement): JsonElement {
return element.editObject { result ->
for ((key, value) in result) {
commentMap[key]?.let { comment ->
result[key] = value.editObject {
it["comment"] = JsonPrimitive(comment)
}
}
}
}
}
}
@Test
fun testMyJsonComment() {
assertJsonFormAndRestored(
CarrierSerializer(),
Carrier("plain", StringData("string1"), IntDataCommented(42)),
"""{"plain":"plain","commented":{"data":"string1","comment":"string_comment"},"intData":{"i":42,"comment":"class_comment"}}"""
)
}
}