Skip to content

Commit

Permalink
Use contextual descriptor where available for contextual deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
OptimumCode committed Jun 24, 2024
1 parent 59a42fe commit 5ddac45
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
17 changes: 14 additions & 3 deletions src/commonMain/kotlin/com/charleskorn/kaml/YamlInput.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.SerialKind
import kotlinx.serialization.descriptors.StructureKind
import kotlinx.serialization.descriptors.getContextualDescriptor
import kotlinx.serialization.encoding.AbstractDecoder
import kotlinx.serialization.modules.SerializersModule

Expand All @@ -47,21 +48,21 @@ public sealed class YamlInput(

is YamlScalar -> when {
descriptor.kind is PrimitiveKind || descriptor.kind is SerialKind.ENUM || descriptor.isInline -> YamlScalarInput(node, yaml, context, configuration)
descriptor.kind is SerialKind.CONTEXTUAL -> YamlContextualInput(node, yaml, context, configuration)
descriptor.kind is SerialKind.CONTEXTUAL -> createContextual(node, yaml, context, configuration, descriptor)
descriptor.kind is PolymorphicKind -> throw MissingTypeTagException(node.path)
else -> throw IncorrectTypeException("Expected ${descriptor.kind.friendlyDescription}, but got a scalar value", node.path)
}

is YamlList -> when (descriptor.kind) {
is StructureKind.LIST -> YamlListInput(node, yaml, context, configuration)
is SerialKind.CONTEXTUAL -> YamlContextualInput(node, yaml, context, configuration)
is SerialKind.CONTEXTUAL -> createContextual(node, yaml, context, configuration, descriptor)
else -> throw IncorrectTypeException("Expected ${descriptor.kind.friendlyDescription}, but got a list", node.path)
}

is YamlMap -> when (descriptor.kind) {
is StructureKind.CLASS, StructureKind.OBJECT -> YamlObjectInput(node, yaml, context, configuration)
is StructureKind.MAP -> YamlMapInput(node, yaml, context, configuration)
is SerialKind.CONTEXTUAL -> YamlContextualInput(node, yaml, context, configuration)
is SerialKind.CONTEXTUAL -> createContextual(node, yaml, context, configuration, descriptor)
is PolymorphicKind -> when (configuration.polymorphismStyle) {
PolymorphismStyle.None ->
throw IncorrectTypeException("Encountered a polymorphic map descriptor but PolymorphismStyle is 'None'", node.path)
Expand All @@ -82,6 +83,16 @@ public sealed class YamlInput(
}
}

private fun createContextual(
node: YamlNode,
yaml: Yaml,
context: SerializersModule,
configuration: YamlConfiguration,
descriptor: SerialDescriptor,
): YamlInput = context.getContextualDescriptor(descriptor)
?.let { createFor(node, yaml, context, configuration, it) }
?: YamlContextualInput(node, yaml, context, configuration)

private fun createPolymorphicMapDeserializer(node: YamlMap, yaml: Yaml, context: SerializersModule, configuration: YamlConfiguration): YamlPolymorphicInput {
val desiredKey = configuration.polymorphismPropertyName
when (val typeName = node.getValue(desiredKey)) {
Expand Down
4 changes: 2 additions & 2 deletions src/commonTest/kotlin/com/charleskorn/kaml/YamlReadingTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2079,7 +2079,7 @@ class YamlReadingTest : FlatFunSpec({
override val descriptor: SerialDescriptor
get() = String.serializer().descriptor

override fun deserialize(decoder: Decoder): Inner = Inner("from context serializer")
override fun deserialize(decoder: Decoder): Inner = Inner(decoder.decodeString())
override fun serialize(encoder: Encoder, value: Inner) = throw UnsupportedOperationException()
}

Expand All @@ -2093,7 +2093,7 @@ class YamlReadingTest : FlatFunSpec({
val result = parser.decodeFromString(Container.serializer(), input)

test("deserializes it using the dynamically installed serializer") {
result shouldBe Container(Inner("from context serializer"))
result shouldBe Container(Inner("this is the input"))
}
}

Expand Down

0 comments on commit 5ddac45

Please sign in to comment.