ste
04/05/2022, 6:21 PM{ "nav": { "watch:" {...} } }
{ "nav": { "browse:" {...} } }
How can I deserialize Nav
based on its key ("watch" | "browse"
)?
This is what I tried:
@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?ste
04/05/2022, 6:50 PM@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 goodAdam S
04/05/2022, 8:06 PMDominaezzz
04/05/2022, 10:16 PMDominaezzz
04/05/2022, 10:18 PMste
04/06/2022, 9:10 AM@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 guessAdam S
04/06/2022, 10:31 AMste
04/07/2022, 7:57 PMDominaezzz
04/07/2022, 9:28 PMDecoder
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.ste
04/08/2022, 7:13 AM