diff options
author | Leonid Startsev <sandwwraith@users.noreply.github.com> | 2022-07-07 13:49:35 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-07 14:49:35 +0300 |
commit | c2327723a8f98fe717c0ec143cff6421b469173e (patch) | |
tree | b92e02de0b8aaf16ce51cc03c300ecbb93c6c888 /formats/json-tests | |
parent | be99c0d780712b47144be528222377575e9b21ff (diff) | |
download | kotlinx.serialization-c2327723a8f98fe717c0ec143cff6421b469173e.tar.gz |
Add @MetaSerializable annotation (#1979)
Co-authored-by: rsinukov <rxsinukov@gmail.com>
Co-authored-by: Vsevolod Tolstopyatov <qwwdfsad@gmail.com>
Diffstat (limited to 'formats/json-tests')
-rw-r--r-- | formats/json-tests/commonTest/src/kotlinx/serialization/features/MetaSerializableJsonTest.kt | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/formats/json-tests/commonTest/src/kotlinx/serialization/features/MetaSerializableJsonTest.kt b/formats/json-tests/commonTest/src/kotlinx/serialization/features/MetaSerializableJsonTest.kt new file mode 100644 index 00000000..25efa6b4 --- /dev/null +++ b/formats/json-tests/commonTest/src/kotlinx/serialization/features/MetaSerializableJsonTest.kt @@ -0,0 +1,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"}}""" + ) + } + +} |