Anuta Vlad Sv
01/30/2023, 2:13 PMJsonTransformingSerializer.transformDeserialize()
and return a null JsonElement if the element is an array. And since the JsonTransformingSerializer
does not currently support nullable types I created a NullableJsonTransformingSerializer
.
I was wondering if there is another way to deserialize the Address, and not use the transformDeserialize().```@Serializable
data class Project(
@Serializable(with = UnwrappingJsonListSerializer::class)
val address: Address?
)
@Serializable
data class Address(val firstName: String)
object UnwrappingJsonListSerializer :
NullableJsonTransformingSerializer<Address>(Address.serializer()) {
override fun nullableTransformDeserialize(element: JsonElement): JsonElement? {
return if (element is JsonArray) null
else element
}
}```
Adam S
01/30/2023, 2:26 PMJsonTransformingSerializer
supports decoding as null - but you have to return the JsonNull
object, instead of a literal null
Anuta Vlad Sv
01/30/2023, 2:39 PMException in thread "main" kotlinx.serialization.json.internal.JsonDecodingException: Expected class kotlinx.serialization.json.JsonObject as the serialized body of com.stockx.stockx.sell.checkout.ui.Address, but had class kotlinx.serialization.json.JsonNullso I tried specifying the serializer as nullable but I get a compile error
Adam S
01/30/2023, 3:02 PMJsonTransformingSerializer
isn’t suitable.
What you could do is decode address
to JsonElement
, and in code convert it to Address
if it’s a JsonObject
@Serializable
data class Project(
@SerialName("address")
private val _address: JsonElement
) {
val address: Address? get() = when (_address) {
is JsonObject -> Json.decodeFromJsonElement(_address)
else -> null
}
}
I like this way, because there’s no custom serializer - it’s just plain Kotlin code. It’s a little weird and verbose though, and the automatic toString()
doesn’t look correct
You could automate it a little by creating a value class that will wrap the logic. Value classes are nice because they’re ‘transparent’ in terms of the actual content, but you can still use them to inject logic into Kotlinx Serialization
@Serializable
data class Project(
private val address: AddressWrapper
)
@Serializable
data class Address(val firstName: String)
@JvmInline
@Serializable
value class AddressWrapper(private val value: JsonElement) {
val address: Address? get() = when (value) {
is JsonObject -> Json.decodeFromJsonElement(value)
else -> null
}
override fun toString() = address.toString()
}
Anuta Vlad Sv
01/30/2023, 4:08 PMAdam S
01/30/2023, 4:11 PM