Skip to content

Commit 34cc4fa

Browse files
committed
fix: Hocon polymorphic serialization
1 parent 1f4a9e5 commit 34cc4fa

File tree

1 file changed

+30
-3
lines changed
  • formats/hocon/src/main/kotlin/kotlinx/serialization/hocon

1 file changed

+30
-3
lines changed

formats/hocon/src/main/kotlin/kotlinx/serialization/hocon/Hocon.kt

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public sealed class Hocon(
139139
}
140140
}
141141

142-
private inner class ConfigReader(val conf: Config) : ConfigConverter<String>() {
142+
private inner class ConfigReader(val conf: Config, private val poly: Boolean = false) : ConfigConverter<String>() {
143143
private var ind = -1
144144

145145
override fun decodeElementIndex(descriptor: SerialDescriptor): Int {
@@ -155,8 +155,12 @@ public sealed class Hocon(
155155
private fun composeName(parentName: String, childName: String) =
156156
if (parentName.isEmpty()) childName else "$parentName.$childName"
157157

158-
override fun SerialDescriptor.getTag(index: Int): String =
159-
composeName(currentTagOrNull.orEmpty(), getConventionElementName(index, useConfigNamingConvention))
158+
override fun SerialDescriptor.getTag(index: Int): String {
159+
return if (!poly) composeName(
160+
currentTagOrNull.orEmpty(),
161+
getConventionElementName(index, useConfigNamingConvention)
162+
) else getElementName(index)
163+
}
160164

161165
override fun decodeNotNullMark(): Boolean {
162166
// Tag might be null for top-level deserialization
@@ -200,6 +204,28 @@ public sealed class Hocon(
200204
}
201205
}
202206

207+
private inner class PolymorphConfigReader(private val conf: Config) : ConfigConverter<String>() {
208+
private var ind = -1
209+
210+
override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder =
211+
when {
212+
// Polymorph should always be object-like I believe?
213+
descriptor.kind.objLike -> ConfigReader(conf, true)
214+
else -> this
215+
}
216+
217+
override fun SerialDescriptor.getTag(index: Int): String = getElementName(index)
218+
219+
override fun decodeElementIndex(descriptor: SerialDescriptor): Int {
220+
ind++
221+
return if (ind >= descriptor.elementsCount) DECODE_DONE else ind
222+
}
223+
224+
override fun <E> getValueFromTaggedConfig(tag: String, valueResolver: (Config, String) -> E): E {
225+
return valueResolver(conf, tag)
226+
}
227+
}
228+
203229
private inner class ListConfigReader(private val list: ConfigList) : ConfigConverter<Int>() {
204230
private var ind = -1
205231

@@ -210,6 +236,7 @@ public sealed class Hocon(
210236

211237
override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder =
212238
when {
239+
descriptor.kind is PolymorphicKind -> PolymorphConfigReader((list[currentTag] as ConfigObject).toConfig())
213240
descriptor.kind.listLike -> ListConfigReader(list[currentTag] as ConfigList)
214241
descriptor.kind.objLike -> ConfigReader((list[currentTag] as ConfigObject).toConfig())
215242
descriptor.kind == StructureKind.MAP -> MapConfigReader(list[currentTag] as ConfigObject)

0 commit comments

Comments
 (0)