Patrick Hum
06/26/2023, 7:17 PM@Serializable(with = OptionalSerializer::class)
sealed interface ApiOptional<out T> {
object None : ApiOptional<Nothing>
data class Some<T>(val value: T) : ApiOptional<T>
}
open class OptionalSerializer<T>(private val valueSerializer: KSerializer<T>) : KSerializer<ApiOptional<T>> {
override val descriptor = valueSerializer.descriptor
override fun serialize(encoder: Encoder, value: ApiOptional<T>) {
when (value) {
is ApiOptional.None -> throw SerializationException()
is ApiOptional.Some -> valueSerializer.serialize(encoder, value.value)
}
}
override fun deserialize(decoder: Decoder): ApiOptional<T> {
return ApiOptional.Some(valueSerializer.deserialize(decoder))
}
}
@Serializable
private data class ThisClassCantBeDeserialized(
val value: ApiOptional<MySealedInterface> = ApiOptional.None,
)
@Serializable
sealed interface MySealedInterface {
@SerialName("MySealedType")
@Serializable
data class MySealedType(
val sealedValue: String,
) : MySealedInterface
}
@Test
fun `test deserialize`() {
val json = Json {
ignoreUnknownKeys = true
explicitNulls = true
coerceInputValues = true
encodeDefaults = true
}
val result = json.decodeFromString(
ThisClassCantBeDeserialized.serializer(),
"""
{
"value": {
"type": "MySealedType",
"sealedValue": "test"
}
}
""".trimIndent(),
)
}
Unexpected JSON token at offset 12: Expected start of the array '[', but had ' ' instead at path: $.value
JSON input: {
"value": {
"type": "MySealedType",
"sealedValue": "test"
}
}
{"value":["MySealedType",{"sealedValue":"test"}]}
but I can’t figure out why its not an objectPatrick Hum
06/26/2023, 7:51 PMdeserialize/serialize
should have been return ApiOptional.Some(decoder.decodeSerializableValue(valueSerializer))