Vampire
08/22/2020, 7:31 PMString or a List<String> in the serialized format, can this somehow be catered for with kotlinx.serialization?
In my concrete case I try using kaml to parse a GitHub workflow yml file.
It can for example have this:
jobs:
job1:
job2:
needs: job1
job3:
needs: [job1, job2]Nikky
08/22/2020, 7:37 PMVampire
08/23/2020, 2:43 AMoutputs:
foo:
description: bar
value: baz
runs:
using: composite
or
outputs:
foo:
description: bar
runs:
using: something else
Meaning the output has a mandatory value property if it is a composite action but no value property if it is a normal action.
Previously I didn't support composite, so I had
@Serializable
data class GitHubAction(
/* ... */
val outputs: Map<String, Output>? = null,
/* ... */
) {
/* ... */
@Serializable
data class Output(
val description: String
)
/* ... */
}
I now changed it to
@Serializable
data class GitHubAction(
/* ... */
val outputs: Map<String, Output>? = null,
/* ... */
) {
/* ... */
sealed class Output {
abstract val description: String
data class NormalOutput(
override val description: String
) : Output()
data class CompositeOutput(
override val description: String,
val value: String
) : Output()
@Serializer(forClass = Output::class)
companion object : KSerializer<Output> {
override val descriptor: SerialDescriptor = SerialDescriptor("net.kautler.dao.GitHubAction.Output", SEALED) {
element("normal", SerialDescriptor("net.kautler.dao.GitHubAction.Output.NormalOutput") {
element("description", PrimitiveDescriptor("net.kautler.dao.GitHubAction.Output.NormalOutput.description", STRING))
})
element("composite", SerialDescriptor("net.kautler.dao.GitHubAction.Output.CompositeOutput") {
element("description", PrimitiveDescriptor("net.kautler.dao.GitHubAction.Output.CompositeOutput.description", STRING))
element("value", PrimitiveDescriptor("net.kautler.dao.GitHubAction.Output.CompositeOutput.value", STRING))
})
}
override fun deserialize(decoder: Decoder): Output {
TODO("deserialize: Not yet implemented")
}
override fun serialize(encoder: Encoder, value: Output) {
TODO("serialize: Not yet implemented")
}
}
}
/* ... */
}
Two questions:
• does it look correct generally or did I completely got something wrong?
• why doesn't it work? The descriptor is used, when I had a TODO() in there it failed, but then on deserialization there comes an error from kaml complaining about the missing polymorphism type tag in the input so it seems the custom serializer is not used.Nikky
08/23/2020, 6:18 AM@Serializable(with=Output.Companion::class) annotation on the outputs property instead to force itVampire
08/23/2020, 9:27 AMCONTEXTUAL instead of SEALED. And it seems to indeed help. Is really CONTEXTUAL appropriate here, or is it a bug, that kaml does not respect the custom serializer? When should you use CONTEXTUAL and when SEALED generally? What is the effective difference?Vampire
08/23/2020, 9:50 AMCONTEXTUAL and SEALED as SEALED is, what the official example uses.Vsevolod Tolstopyatov [JB]
08/27/2020, 4:50 PMVampire
08/27/2020, 8:39 PM