Contextually register in SerializersModule nullable type
Registering serializer module as contextual and passing a KSerializer that has nullable type is not allowed. It is needed due to bad backend responses when field value is not null, but empty string instead.
Example: val module = SerializersModule { contextual(serializer = LocalDateSerializer) -> shows error Type mismatch. Required: Any Found: LocalDate? }
LocalDateSerializer class @Serializer(forClass = LocalDate::class) object LocalDateSerializer : KSerializer<LocalDate?> { private val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd") override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDate?", PrimitiveKind.STRING).nullable
override fun serialize(encoder: Encoder, value: LocalDate?) {
encoder.encodeString(formatter.format(value))
}
override fun deserialize(decoder: Decoder): LocalDate? {
val output = decoder.decodeString()
val result = try {
LocalDate.from(formatter.parse(output))
} catch (e: DateTimeParseException) {
ZonedDateTime.parse(output).toLocalDate()
} catch (e: Exception) {
null
}
return result
}
}
The problem is in KClass<T> that requires T to be non-nullable and inferred in this overload automatically. However, I think it may be possible to change the signature of contextual(kClass: KClass<T>, serializer: KSerializer<T>) overload.
Is there a workaround? I'm currently stuck on this, I'm surprised it's not possible to serialize nullable values.
The same problem here, registering nullable string serializer like this:
object NullableStringSerializer : KSerializer<String?> {
private val delegate = serializer<String>().nullable
override val descriptor: SerialDescriptor = delegate.descriptor
override fun serialize(encoder: Encoder, value: String?) {
delegate.serialize(encoder, value?.ifEmpty { null })
}
override fun deserialize(decoder: Decoder): String? {
return delegate.deserialize(decoder)?.ifEmpty { null }
}
}
val module = SerializersModule {
contextual(NullableStringSerializer)
// ~~~~~~~~~~~~~~~~~~~~~~~~
}
This results in error:
Type mismatch.
Required: Any
Found: String?
Is there any workaround available please?
@morki Maybe contextual(NullableStringSerializer as KSerializer<String>) would work