shusek
06/17/2021, 10:49 AMpolymorphic
but i not sure if it was intended for such cases. Current working code below:
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.encoding.decodeStructure
import kotlinx.serialization.json.Json
import org.junit.Assert
import org.junit.Test
class WSampleTest {
val parser = Json {
isLenient = true
ignoreUnknownKeys = true
allowSpecialFloatingPointValues = true
useArrayPolymorphism = false
}
@Test
fun shouldParseFirst() {
val string = """{"type":"first", "data":{"name":"test"}}"""
val firstObj = parser.decodeFromString(CustomClassObjSerializer, string)
Assert.assertEquals(CustomClassSpecificFirst("test"), firstObj)
}
@Test
fun shouldParseSecond() {
val string = """{"type":"second", "data":{"otherName":"otherTest"}}"""
val firstObj = parser.decodeFromString(CustomClassObjSerializer, string)
Assert.assertEquals(CustomClassSpecificSecond("otherTest"), firstObj)
}
}
@Serializer(forClass = CustomClassObj::class)
object CustomClassObjSerializer : KSerializer<CustomClassObj> {
override val descriptor: SerialDescriptor = CustomClassBoxWithType.serializer().descriptor
override fun deserialize(decoder: Decoder): CustomClassObj {
decoder.decodeStructure(descriptor) {
decodeElementIndex(descriptor)
val serializer = when (decodeStringElement(descriptor, 0)) {
"first" -> CustomClassSpecificFirst.serializer()
"second" -> CustomClassSpecificSecond.serializer()
else -> UnknownMessage.serializer()
}
decodeElementIndex(descriptor)
return decodeSerializableElement(
descriptor,
1,
serializer
)
}
}
override fun serialize(encoder: Encoder, value: CustomClassObj) =
throw IllegalStateException("serialize is not supported")
}
@Serializable
data class CustomClassBoxWithType(val type: String, val data: CustomClassObj)
@Serializable
abstract class CustomClassObj
@Serializable
data class CustomClassSpecificFirst(val name: String) : CustomClassObj()
@Serializable
data class CustomClassSpecificSecond(val otherName: String) : CustomClassObj()
@Serializable
object UnknownMessage : CustomClassObj()