Skip to content

Commit 7e03eed

Browse files
authored
Support diamond inheritance of sealed interfaces in SealedClassSerializer (#1958)
Fixes #1937
1 parent 3f8378d commit 7e03eed

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

core/commonMain/src/kotlinx/serialization/SealedSerializer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public class SealedClassSerializer<T : Any>(
105105
element("type", String.serializer().descriptor)
106106
val elementDescriptor =
107107
buildSerialDescriptor("kotlinx.serialization.Sealed<${baseClass.simpleName}>", SerialKind.CONTEXTUAL) {
108-
subclassSerializers.forEach {
108+
subclassSerializers.distinct().forEach {
109109
val d = it.descriptor
110110
element(d.serialName, d)
111111
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package kotlinx.serialization.features.sealed
2+
3+
import kotlinx.serialization.*
4+
import kotlinx.serialization.descriptors.*
5+
import kotlinx.serialization.json.*
6+
import kotlin.test.*
7+
8+
class SealedDiamondTest : JsonTestBase() {
9+
10+
@Serializable
11+
sealed interface A {}
12+
13+
@Serializable
14+
sealed interface B : A {}
15+
16+
@Serializable
17+
sealed interface C : A {}
18+
19+
@Serializable
20+
@SerialName("X")
21+
data class X(val i: Int) : B, C
22+
23+
@Test
24+
fun testMultipleSuperSealedInterfacesDescriptor() {
25+
val subclasses = A.serializer().descriptor.getElementDescriptor(1).elementDescriptors.map { it.serialName }
26+
assertEquals(listOf("X"), subclasses)
27+
}
28+
29+
@Test
30+
fun testMultipleSuperSealedInterfaces() {
31+
@Serializable
32+
data class Carrier(val a: A, val b: B, val c: C)
33+
assertJsonFormAndRestored(
34+
Carrier.serializer(),
35+
Carrier(X(1), X(2), X(3)),
36+
"""{"a":{"type":"X","i":1},"b":{"type":"X","i":2},"c":{"type":"X","i":3}}"""
37+
)
38+
}
39+
40+
}

0 commit comments

Comments
 (0)