Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contextually register in SerializersModule nullable type #1826

Open
laurynas-agmis opened this issue Jan 12, 2022 · 4 comments
Open

Contextually register in SerializersModule nullable type #1826

laurynas-agmis opened this issue Jan 12, 2022 · 4 comments

Comments

@laurynas-agmis
Copy link

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
}

}

@sandwwraith
Copy link
Member

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.

@sandwwraith sandwwraith changed the title SerializersModule contextual nullable type Contextually register in SerializersModule nullable type Jan 18, 2022
@CLOVIS-AI
Copy link

Is there a workaround? I'm currently stuck on this, I'm surprised it's not possible to serialize nullable values.

@morki
Copy link

morki commented Jan 31, 2023

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?

@sandwwraith
Copy link
Member

@morki Maybe contextual(NullableStringSerializer as KSerializer<String>) would work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants