commonMain.internal.RootClassSerializer.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of knbt Show documentation
Show all versions of knbt Show documentation
Minecraft NBT support for kotlinx.serialization
The newest version!
package net.benwoodworth.knbt.internal
import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.*
@OptIn(ExperimentalSerializationApi::class)
private fun rootClassSerialDescriptor(classDescriptor: SerialDescriptor): SerialDescriptor =
buildClassSerialDescriptor("net.benwoodworth.knbt.internal.RootClass", classDescriptor) {
element(classDescriptor.serialName, classDescriptor)
}
internal class RootClassSerializer(
private val classSerializer: SerializationStrategy,
) : SerializationStrategy {
override val descriptor: SerialDescriptor = rootClassSerialDescriptor(classSerializer.descriptor)
override fun serialize(encoder: Encoder, value: T) {
encoder.encodeStructure(descriptor) {
encodeSerializableElement(descriptor, 0, classSerializer, value)
}
}
}
internal class RootClassDeserializer(
private val classDeserializer: DeserializationStrategy,
) : DeserializationStrategy {
override val descriptor: SerialDescriptor = rootClassSerialDescriptor(classDeserializer.descriptor)
@OptIn(ExperimentalSerializationApi::class)
override fun deserialize(decoder: Decoder): T {
var root: T? = null
var rootDecoded = false
decoder.decodeStructure(descriptor) {
// loop label: https://youtrack.jetbrains.com/issue/KT-43943
loop@ while (true) {
when (val index = decodeElementIndex(descriptor)) {
0 -> {
root = decodeSerializableElement(descriptor, index, classDeserializer)
rootDecoded = true
}
CompositeDecoder.DECODE_DONE -> break@loop
else -> error("Unexpected index: $index")
}
}
}
if (!rootDecoded) {
val serialName = classDeserializer.descriptor.serialName
throw NbtDecodingException(
"Root tag '$serialName' is required for class with serial name '$serialName', but it was missing."
)
}
@Suppress("UNCHECKED_CAST")
return root as T
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy