OpenUnionSerializer
Base serializer for generator-emitted open unions.
A generated subclass implements three methods that together cover both directions of the wire mapping without needing reflection:
selectKnownDeserializer: given a normalized
$typestring from an incoming wire value, return the matching known member's serializer (ornullto route to the Unknown fallback on decode).selectKnownSerializer: given an in-memory value, return its serializer (or
nullto route to the Unknown fallback on encode).unknownSerializer: return the owning union's UnknownMemberSerializer.
The base class handles $type extraction, nsid/nsid#main normalization, and injection of the $type key on encode (concrete @Serializable data classes produce objects without a discriminator, so we prepend it).
Typical generator output:
object MediaSerializer : OpenUnionSerializer<Media>(Media::class) {
override fun selectKnownDeserializer(type: String) = when (type) {
"app.bsky.embed.images" -> Media.Images.serializer()
"app.bsky.embed.video" -> Media.Video.serializer()
"app.bsky.embed.external" -> Media.External.serializer()
else -> null
}
override fun selectKnownSerializer(value: Media) = when (value) {
is Media.Images -> Media.Images.serializer()
is Media.Video -> Media.Video.serializer()
is Media.External -> Media.External.serializer()
is Media.Unknown -> null
}
override fun unknownSerializer() = MediaUnknownSerializer
}