Hi all! Given the following JSONs: ```{ "nav": { "...
# serialization
s
Hi all! Given the following JSONs:
Copy code
{ "nav": { "watch:" {...} } }
{ "nav": { "browse:" {...} } }
How can I deserialize
Nav
based on its key (
"watch" | "browse"
)? This is what I tried:
Copy code
@Serializable
data class Nav(
  val action: Action
)

@Serializable
sealed class Action {
  @Serializable
  @SerialName("watch")
  data class Watch(...) : Action()

  @Serializable
  @SerialName("browse")
  data class Browse(...) : Action()
}
But it doesn't work -
Field 'action' is required for type with serial name Nav
; what am I missing?
Copy code
@Serializable(with = Nav.Serializer::class)
sealed class Nav {
    @Serializable
    data class Watch(
        val watch: Watch
    ) : Nav() {
        @Serializable
        data class Watch(val v: String)
    }

    @Serializable
    data class Browse(
        val browse: Browse
    ) : Nav() {
        @Serializable
        data class Browse(val k: Int)
    }

    object Serializer : JsonContentPolymorphicSerializer<Nav>(Nav::class) {
        override fun selectDeserializer(element: JsonElement) = when {
            "browse" in element.jsonObject -> Browse.serializer()
            "watch" in element.jsonObject -> Watch.serializer()
            else -> TODO()
        }
    }
}
This works... but it doesn't look good
👍 2
a
I think what you've written is the best option. What don't you like about?
d
Yeah you'll definitely need a custom serialiser for that.
That solution is the simplest option. There's more efficient but complex options as well.
s
I don't like its verbosity/complexity. Look at this very simple (!!) workaround:
Copy code
@Serializable
data class Nav(
    private val watch: Action.Watch?,
    private val browse: Action.Browse?
) {
    @Transient
    val action = (watch ?: browse)!!
}

@Serializable
sealed class Action {
    @Serializable
    data class Watch(val v: String) : Action()

    @Serializable
    data class Browse(val k: Int) : Action()
}
The only downside is the extra key lookup, which is irrelevant I guess
a
That's a pretty neat alternative!
s
@Dominaezzz Yup, the first solution is slower (of milliseconds, nobody cares) than the workaround I posted later. Out of curiosity, what's the more efficient but complex option?
d
Custom serializer. You'd have to traverse the
Decoder
yourself. It's not much better than the second solution though. It's only better if you want the `class`es to have a different shape.
s
Ty!