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

KotlinxSerialization.asFormatString polymorphic serialization error #819

Open
oharaandrew314 opened this issue Nov 20, 2022 · 0 comments
Open

Comments

@oharaandrew314
Copy link
Contributor

oharaandrew314 commented Nov 20, 2022

KotlinxSerialization.asFormatString seems incapable of properly handling polymorphic types; it fails to properly serialize the type parameter. I believe this works with raw kotlinx and with lenses because they both reifiy the base provided type, rather than rely on the runtime type.

I don't really see a way around this short of extensive modifications to asFormatString to reify the type. However, doing so would also allow the http4k-format-csv module to become an AutoMarshalling, as this was a limiting issue.

Thoughts? Live with and document the limitation? Or try to reify the type in asFormatString?

See the provided tests below, where serialize sealed class - http4k asFormatString fails.

@Serializable
sealed interface Animal {
    val name: String
}

@Serializable
@SerialName("cat")
data class Cat(
    override val name: String,
    val lives: Int,
): Animal

val json = """{"type":"cat","name":"Bandit","lives":8}"""
val obj = Cat("Bandit", 8)
val lens = KotlinxSerialization.autoBody<Animal>().toLens()

@Test
fun `serialize sealed class - kotlinx encodeToString`() {
    assertThat(
        Json.encodeToString(obj as Animal),
        equalTo(json)
    )
}
// PASS

@Test
fun `serialize sealed class - http4k asFormatString`() {
    assertThat(
        KotlinxSerialization.asFormatString(obj as Animal),
        equalTo("""{"type":"cat","name":"Bandit","lives":8}""")
    )
} // FAIL.  Was {"name":"Bandit","lives":8}"

@Test
fun `serialize sealed class - http4k lens`() {
    assertThat(
        Response(Status.OK).with(lens of obj).bodyString(),
        equalTo(json)
    )
}
// PASS

@Test
fun `deserialize sealed class - kotlinx decodeFromString`() {
    assertThat(
        Json.decodeFromString<Animal>(json),
        equalTo(obj)
    )
}
// PASS

@Test
fun `deserialize sealed class - http4k asA`() {
    assertThat(
        KotlinxSerialization.asA<Animal>(json),
        equalTo(obj)
    )
}
// PASS

@Test
fun `deserialize sealed class - http4k lens`() {
    assertThat(
        lens(Response(Status.OK).body(json)),
        equalTo(obj)
    )
}
// PASS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant