-
-
Notifications
You must be signed in to change notification settings - Fork 19
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
[Question] How to implement KeyDispatchCodec
like registry codec with codec factory?
#85
Comments
Achieve with below. Open for advice @OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class)
open class DispatchedCodecSerializer<Out : Any, Type>(
val targetCodec: Codec<Type>,
val type: Function<Out, Type>,
val codec: Function<Type, Codec<Out>>,
private val serialName: String
) : KSerializer<Out> {
override val descriptor =
buildSerialDescriptor(serialName, PolymorphicKind.OPEN) {
element("type", String.serializer().descriptor)
element(
"value",
buildSerialDescriptor(
"DispatchedCodecSerializer<$serialName>",
SerialKind.CONTEXTUAL
)
)
}
override fun deserialize(decoder: Decoder): Out {
if (decoder !is DynamicDecoder<*>) {
throw UnsupportedOperationException(
"Codec serializers can only be used in Dynamic serialization"
)
}
val compositeDecoder = decoder.beginStructure(descriptor)
var currentType: Type
var elementCodec: Codec<Out>? = null
var out: Out? = null
while (true) {
when (val index = compositeDecoder.decodeElementIndex(descriptor)) {
0 -> {
currentType =
compositeDecoder.decodeSerializableElement(
descriptor,
0,
CodecSerializerAdapter(targetCodec, serialName)
)
elementCodec = codec.apply(currentType)
}
1 ->
out =
compositeDecoder.decodeSerializableElement(
descriptor,
1,
CodecSerializerAdapter(elementCodec!!, serialName)
)
CompositeDecoder.DECODE_DONE -> break
else -> error("Unexpected index: $index")
}
}
decoder.endStructure(descriptor)
return out!!
}
override fun serialize(encoder: Encoder, value: Out) {
if (encoder !is DynamicEncoder<*>) {
throw UnsupportedOperationException(
"Codec serializers can only be used in Dynamic serialization"
)
}
val compositeEncoder = encoder.beginStructure(descriptor)
val currentType = type.apply(value)
compositeEncoder.encodeSerializableElement(
descriptor,
0,
CodecSerializerAdapter(targetCodec, serialName),
currentType
)
val elementCodec = codec.apply(currentType)
compositeEncoder.encodeSerializableElement(
descriptor,
1,
CodecSerializerAdapter(elementCodec, serialName),
value
)
encoder.endStructure(descriptor)
}
}
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I will implement a
KeyDispatchCodec
for my custom registry with the Kotlin library codec factory.How can I make the codec factory handle the polymorphic and get codec from the registry?
For example:
BuiltInRegistries.RECIPE_SERIALIZER.byNameCodec().dispatch(Recipe::getSerializer, RecipeSerializer::codec)
The text was updated successfully, but these errors were encountered: