Skip to content

Commit ff1621c

Browse files
committed
fix: Hocon polymorphic serialization
1 parent 31d779f commit ff1621c

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
@@ -145,7 +145,7 @@ public sealed class Hocon(
145145

146146
}
147147

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

151151
override fun decodeElementIndex(descriptor: SerialDescriptor): Int {
@@ -161,8 +161,12 @@ public sealed class Hocon(
161161
private fun composeName(parentName: String, childName: String) =
162162
if (parentName.isEmpty()) childName else "$parentName.$childName"
163163

164-
override fun SerialDescriptor.getTag(index: Int): String =
165-
composeName(currentTagOrNull.orEmpty(), getConventionElementName(index, useConfigNamingConvention))
164+
override fun SerialDescriptor.getTag(index: Int): String {
165+
return if (!poly) composeName(
166+
currentTagOrNull.orEmpty(),
167+
getConventionElementName(index, useConfigNamingConvention)
168+
) else getElementName(index)
169+
}
166170

167171
override fun decodeNotNullMark(): Boolean {
168172
// Tag might be null for top-level deserialization
@@ -206,6 +210,28 @@ public sealed class Hocon(
206210
}
207211
}
208212

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

@@ -216,6 +242,7 @@ public sealed class Hocon(
216242

217243
override fun beginStructure(descriptor: SerialDescriptor): CompositeDecoder =
218244
when {
245+
descriptor.kind is PolymorphicKind -> PolymorphConfigReader((list[currentTag] as ConfigObject).toConfig())
219246
descriptor.kind.listLike -> ListConfigReader(list[currentTag] as ConfigList)
220247
descriptor.kind.objLike -> ConfigReader((list[currentTag] as ConfigObject).toConfig())
221248
descriptor.kind == StructureKind.MAP -> MapConfigReader(list[currentTag] as ConfigObject)

0 commit comments

Comments
 (0)