orchestr7 / ktoml

Kotlin Multiplatform parser and compile-time serializer/deserializer for TOML format (Native, JS, JVM) based on KxS
https://akuleshov7.github.io/ktoml
MIT License
455 stars 25 forks source link

Feature request: support value classes #237

Closed covercash2 closed 1 year ago

covercash2 commented 1 year ago

I'm not sure if this is in the intended scope for this effort, but I am using an ECS system to model some data. This system uses types as markers for a lot of things, and I would like to be able to serialize that data. I'm looking at TOML because I'm familiar with it from other platforms, and it reads nice.

In other projects, I've used kotlinx serialization with JSON and value classes effortlessly:

@Serializable
@JvmInline
value class Num(val int: Int)

@Serializable
data class Nums(
    val num1: Num,
    val num2: Num,
)

val num1 = Num(1)
val num2 = Num(2)

val nums = Nums(num1, num2)

val zero = Json.encodeToString(num1)
println(zero)
val one = Json.encodeToString(num2)
println(one)
val two = Json.encodeToString(nums)
println(two

Output:

1
2
{"num1":1,"num2":2}

The same code using TOML:

val zero = Toml.encodeToString(num1)
println(zero)
val one = Toml.encodeToString(num2)
println(one)
val two = Toml.encodeToString(nums)
println(two)

Throws an Exception:

com.akuleshov7.ktoml.exceptions.InternalEncodingException: Key is not set It's an internal error - you can do nothing with it, please report it to https://github.com/akuleshov7/ktoml/
com.akuleshov7.ktoml.exceptions.InternalEncodingException: Key is not set It's an internal error - you can do nothing with it, please report it to https://github.com/akuleshov7/ktoml/
    at kotlin.Throwable#<init>(/opt/buildAgent/work/f43969c6214a19e7/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Throwable.kt:28)
    at kotlin.Exception#<init>(/opt/buildAgent/work/f43969c6214a19e7/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:23)
    at kotlin.RuntimeException#<init>(/opt/buildAgent/work/f43969c6214a19e7/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:34)
    at kotlin.IllegalArgumentException#<init>(/opt/buildAgent/work/f43969c6214a19e7/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/Exceptions.kt:59)
    at kotlinx.serialization.SerializationException#<init>(/opt/buildAgent/work/b2fef8360e1bcf3d/core/commonMain/src/kotlinx/serialization/SerializationExceptions.kt:48)
    at com.akuleshov7.ktoml.exceptions.TomlEncodingException#<init>(/Users/runner/work/ktoml/ktoml/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/exceptions/TomlEncodingException.kt:7)
    at com.akuleshov7.ktoml.exceptions.InternalEncodingException#<init>(/Users/runner/work/ktoml/ktoml/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/exceptions/TomlEncodingException.kt:11)
    at com.akuleshov7.ktoml.encoders.TomlEncoderAttributes#keyOrThrow(/Users/runner/work/ktoml/ktoml/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/encoders/TomlEncoderAttributes.kt:35)
    at com.akuleshov7.ktoml.encoders.TomlMainEncoder#appendValue(/Users/runner/work/ktoml/ktoml/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/encoders/TomlMainEncoder.kt:43)
    at com.akuleshov7.ktoml.encoders.TomlAbstractEncoder#encodeLong(/Users/runner/work/ktoml/ktoml/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/encoders/TomlAbstractEncoder.kt:99)
    at com.akuleshov7.ktoml.encoders.TomlAbstractEncoder#encodeInt(/Users/runner/work/ktoml/ktoml/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/encoders/TomlAbstractEncoder.kt:145)
    at tabletop.Num.$serializer#serialize(/Users/chrash/code/tabletop/src/commonTest/kotlin/tabletop/FileIoTest.kt:1)
    at tabletop.Num.$serializer#$<bridge-NNNNB>serialize(kotlinx.serialization.encoding.Encoder;tabletop.Num){}(/Users/chrash/code/tabletop/src/commonTest/kotlin/tabletop/FileIoTest.kt:1)
    at com.akuleshov7.ktoml.encoders.TomlMainEncoder.Companion#encode(/Users/runner/work/ktoml/ktoml/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/encoders/TomlMainEncoder.kt:143)
    at com.akuleshov7.ktoml.Toml#encodeToString(/Users/runner/work/ktoml/ktoml/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/Toml.kt:51)
    at tabletop.FileIoTest#test(/Users/chrash/code/tabletop/src/commonTest/kotlin/tabletop/FileIoTest.kt:72)
    at tabletop.$FileIoTest$test$0.$test(/Users/chrash/code/tabletop/src/commonTest/kotlin/tabletop/FileIoTest.kt:66)
    at tabletop.$FileIoTest$test$0.$test(/Users/chrash/code/tabletop/src/commonTest/kotlin/tabletop/FileIoTest.kt:66)
    at kotlin.native.internal.test.BaseClassSuite.TestCase#run(/opt/buildAgent/work/f43969c6214a19e7/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestSuite.kt:92)
    at kotlin.native.internal.test.TestRunner.run#internal(/opt/buildAgent/work/f43969c6214a19e7/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:248)
    at kotlin.native.internal.test.TestRunner.runIteration#internal(/opt/buildAgent/work/f43969c6214a19e7/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:274)
    at kotlin.native.internal.test.TestRunner#run(/opt/buildAgent/work/f43969c6214a19e7/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/TestRunner.kt:289)
    at kotlin.native.internal.test#testLauncherEntryPoint(/opt/buildAgent/work/f43969c6214a19e7/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:33)
    at kotlin.native.internal.test#main(/opt/buildAgent/work/f43969c6214a19e7/kotlin/kotlin-native/runtime/src/main/kotlin/kotlin/native/internal/test/Launcher.kt:38)
    at <global>.Konan_start(/Users/chrash/.gradle/daemon/8.2.1/entryPointOwner:1)
    at <global>.Init_and_run_start(Unknown Source)
    at <global>.start(Unknown Source)

When I have been able to get some data to serialize, the output is a bit wonky:

[strength]
    [strength.strength]
        strength = 10

[dexterity]
    [dexterity.dexterity]
        dexterity = 10

Expected:

strength = 10
dexterity = 10

Setup

Using Kotlin Multiplatform with Kotlin Version 1.9.0 Ktoml Version 0.5.0 Compared against kotlinx-serialization-json version 1.5.1 Native architecture: Apple ARM M2 JDK 17

orchestr7 commented 1 year ago

Definitely a bug, will try to investigate