BenWoodworth / knbt

Kotlin NBT library for kotlinx.serialization
GNU Lesser General Public License v3.0
72 stars 2 forks source link

Back `Nbt*Array`s with `List`s, and encode arrays as `NbtList` by default, and require `@NbtArray` #34

Open BenWoodworth opened 1 year ago

BenWoodworth commented 1 year ago
BenWoodworth commented 2 weeks ago

Additional problem with the way it's done in v0.11, and deciding if it should be an NBT Array by detecting if the descriptor is a builtin array serializer's descriptor:

When delegating the serialization process to a Byte/Int/LongArray's serializer the standard way, the outer serializer has to rename the array's serializer (since the serial name needs to be unique). Because of this, the descriptor is no longer equal, meaning the serializer's descriptor alone can't be used to introspect the NBT's schema. Only once the serialization logic is executed will the encoder/decoder see the array serializer's descriptor and be able to determine that the SerialKind.LIST value should be an NBT array.

BenWoodworth commented 3 days ago

There should be a way for a descriptor to specify that it definitely is or is not an NBT array.

For example, this should not work:

@Serializable
class MyClass(
    @NbtArray
    val collection: NbtList<*>
)

Having an optional way to specify could solve this:

annotation class NbtArray(val isNbtArray: Boolean = true)

NbtList could have @NbtArray(false) in its descriptor to disallow this.

And similarly, the NBT arrays could have @NbtArray, preventing a NBT array property from being marked with @NbtArray(false)

BenWoodworth commented 3 days ago

It could also be useful to have a configuration option to encode LIST kinds of BYTE/INT/LONG as arrays unless marked with @NbtArray(false).

Inspired by kotlinx.serialization's CborConfiguration.alwaysUseByteString in v1.7.2, applying @ByteString by default