Skip to content

Commit

Permalink
Fix NbtTag-typed values not encoding correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
BenWoodworth committed Oct 4, 2022
1 parent 9278b40 commit d288924
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 7 deletions.
14 changes: 10 additions & 4 deletions src/commonMain/kotlin/NbtDecoder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import kotlinx.serialization.PolymorphicSerializer
import kotlinx.serialization.builtins.ByteArraySerializer
import kotlinx.serialization.builtins.IntArraySerializer
import kotlinx.serialization.builtins.LongArraySerializer
import kotlinx.serialization.descriptors.PolymorphicKind
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.StructureKind
import kotlinx.serialization.encoding.AbstractDecoder
import kotlinx.serialization.encoding.CompositeDecoder
import kotlinx.serialization.encoding.Decoder
import net.benwoodworth.knbt.internal.NbtDecodingException
import net.benwoodworth.knbt.internal.NbtEncodingException

public sealed interface NbtDecoder : Decoder {
public val nbt: NbtFormat
Expand Down Expand Up @@ -81,10 +83,14 @@ internal abstract class AbstractNbtDecoder : AbstractDecoder(), NbtDecoder, Comp
ByteArraySerializer() -> decodeByteArray() as T
IntArraySerializer() -> decodeIntArray() as T
LongArraySerializer() -> decodeLongArray() as T
is PolymorphicSerializer<*> -> when (deserializer.baseClass) {
NbtTag::class -> decodeNbtTag() as T
else -> throw NbtDecodingException("Polymorphic serialization is not yet supported")
else -> when {
deserializer is PolymorphicSerializer && deserializer.baseClass == NbtTag::class -> {
decodeNbtTag() as T
}
deserializer.descriptor.kind is PolymorphicKind -> {
throw NbtEncodingException("Polymorphic serialization is not yet supported")
}
else -> super<AbstractDecoder>.decodeSerializableValue(deserializer)
}
else -> super<AbstractDecoder>.decodeSerializableValue(deserializer)
}
}
10 changes: 7 additions & 3 deletions src/commonMain/kotlin/NbtEncoder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,16 @@ internal abstract class AbstractNbtEncoder : AbstractEncoder(), NbtEncoder, Comp

override fun <T> encodeSerializableValue(serializer: SerializationStrategy<T>, value: T): Unit =
when (serializer) {
NbtTag.serializer() -> encodeNbtTag(value as NbtTag)
ByteArraySerializer() -> encodeByteArray(value as ByteArray)
IntArraySerializer() -> encodeIntArray(value as IntArray)
LongArraySerializer() -> encodeLongArray(value as LongArray)
else -> when (serializer.descriptor.kind) {
is PolymorphicKind -> throw NbtEncodingException("Polymorphic serialization is not yet supported")
else -> when {
serializer is PolymorphicSerializer && serializer.baseClass == NbtTag::class -> {
encodeNbtTag(value as NbtTag)
}
serializer.descriptor.kind is PolymorphicKind -> {
throw NbtEncodingException("Polymorphic serialization is not yet supported")
}
else -> super<AbstractEncoder>.encodeSerializableValue(serializer, value)
}
}
Expand Down
51 changes: 51 additions & 0 deletions src/commonTest/kotlin/NbtTagPolymorphismTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package net.benwoodworth.knbt

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlin.test.Test
import kotlin.test.assertEquals

class NbtTagPolymorphismTest {
private val nbt = Nbt {
variant = NbtVariant.Java
compression = NbtCompression.None
}

@Serializable
@SerialName("")
private data class NbtTagContainer(
val nbtTag: NbtTag,
)

@Test
fun Should_encode_NbtCompound_to_NbtTag_property_correctly() {
val compound = buildNbtCompound {
put("entry", "Hello, world!")
}

val toEncode = NbtTagContainer(compound)

assertEquals(
expected = buildNbtCompound("") {
put(NbtTagContainer::nbtTag.name, compound)
},
actual = nbt.encodeToNbtTag(NbtTagContainer.serializer(), toEncode),
)
}

@Test
fun Should_decode_NbtCompound_from_NbtTag_property_correctly() {
val compound = buildNbtCompound {
put("entry", "Hello, world!")
}

val toDecode = buildNbtCompound("") {
put(NbtTagContainer::nbtTag.name, compound)
}

assertEquals(
expected = NbtTagContainer(compound),
actual = nbt.decodeFromNbtTag(NbtTagContainer.serializer(), toDecode),
)
}
}

0 comments on commit d288924

Please sign in to comment.