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