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