diff --git a/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTransformingSerializerTest.kt b/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTransformingSerializerTest.kt index 516587f5e..9398e95f4 100644 --- a/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTransformingSerializerTest.kt +++ b/formats/json-tests/commonTest/src/kotlinx/serialization/json/JsonTransformingSerializerTest.kt @@ -98,4 +98,29 @@ class JsonTransformingSerializerTest : JsonTestBase() { assertEquals(correctExample, json.decodeFromString(DocExample.serializer(), """{"data":["str1"]}""", streaming)) assertEquals(correctExample, json.decodeFromString(DocExample.serializer(), """{"data":"str1"}""", streaming)) } + + // Wraps/unwraps {"data":null} to just `null`, because StringData.data is not nullable + object NullableStringDataSerializer : JsonTransformingSerializer(StringData.serializer().nullable) { + override fun transformDeserialize(element: JsonElement): JsonElement { + val data = element.jsonObject["data"]?.jsonPrimitive + if (data?.contentOrNull.isNullOrBlank()) return JsonNull + return element + } + + override fun transformSerialize(element: JsonElement): JsonElement { + return if (element is JsonNull) JsonObject(mapOf("data" to JsonNull)) + else element + } + } + + @Serializable + data class NullableStringDataHolder(@Serializable(NullableStringDataSerializer::class) val stringData: StringData?) + + @Test + fun testNullableTransformingSerializer() { + val normalInput = """{"stringData":{"data":"str1"}}""" + val nullInput = """{"stringData":{"data":null}}""" + assertJsonFormAndRestored(NullableStringDataHolder.serializer(), NullableStringDataHolder(StringData("str1")), normalInput) + assertJsonFormAndRestored(NullableStringDataHolder.serializer(), NullableStringDataHolder(null), nullInput) + } } diff --git a/formats/json/api/kotlinx-serialization-json.klib.api b/formats/json/api/kotlinx-serialization-json.klib.api index b91b90253..18c1078ee 100644 --- a/formats/json/api/kotlinx-serialization-json.klib.api +++ b/formats/json/api/kotlinx-serialization-json.klib.api @@ -111,7 +111,7 @@ abstract class <#A: kotlin/Any> kotlinx.serialization.json/JsonContentPolymorphi final fun serialize(kotlinx.serialization.encoding/Encoder, #A) // kotlinx.serialization.json/JsonContentPolymorphicSerializer.serialize|serialize(kotlinx.serialization.encoding.Encoder;1:0){}[0] } -abstract class <#A: kotlin/Any> kotlinx.serialization.json/JsonTransformingSerializer : kotlinx.serialization/KSerializer<#A> { // kotlinx.serialization.json/JsonTransformingSerializer|null[0] +abstract class <#A: kotlin/Any?> kotlinx.serialization.json/JsonTransformingSerializer : kotlinx.serialization/KSerializer<#A> { // kotlinx.serialization.json/JsonTransformingSerializer|null[0] constructor (kotlinx.serialization/KSerializer<#A>) // kotlinx.serialization.json/JsonTransformingSerializer.|(kotlinx.serialization.KSerializer<1:0>){}[0] open val descriptor // kotlinx.serialization.json/JsonTransformingSerializer.descriptor|{}descriptor[0] diff --git a/formats/json/commonMain/src/kotlinx/serialization/json/JsonTransformingSerializer.kt b/formats/json/commonMain/src/kotlinx/serialization/json/JsonTransformingSerializer.kt index 22d87a72b..4c1ef0767 100644 --- a/formats/json/commonMain/src/kotlinx/serialization/json/JsonTransformingSerializer.kt +++ b/formats/json/commonMain/src/kotlinx/serialization/json/JsonTransformingSerializer.kt @@ -52,7 +52,7 @@ import kotlinx.serialization.json.internal.* * Should be able to parse [JsonElement] from [transformDeserialize] function. * Usually, default [serializer] is sufficient. */ -public abstract class JsonTransformingSerializer( +public abstract class JsonTransformingSerializer( private val tSerializer: KSerializer ) : KSerializer {