• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download

<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