-
Notifications
You must be signed in to change notification settings - Fork 619
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix value class encoding in various corner cases (#2242)
- Value class is located at top-level, but wraps non-primitive and thus does not fall in 'primitive on top-level' branch - Value class is a subclass in a polymorphic hierarchy, but either is primitive or explicitly recorded without type info Note that type info is omitted in the latter case and 'can't add type info to primitive' error is not thrown deliberately, as there seems to be use-cases for that. Fixes #1774 Fixes #2159
- Loading branch information
1 parent
5084435
commit fc9aef5
Showing
6 changed files
with
126 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
74 changes: 74 additions & 0 deletions
74
...commonTest/src/kotlinx/serialization/features/inline/ValueClassesInSealedHierarchyTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
/* | ||
* Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. | ||
*/ | ||
|
||
package kotlinx.serialization.features.inline | ||
|
||
import kotlinx.serialization.* | ||
import kotlinx.serialization.json.* | ||
import kotlinx.serialization.test.* | ||
import kotlin.jvm.* | ||
import kotlin.test.* | ||
|
||
class ValueClassesInSealedHierarchyTest : JsonTestBase() { | ||
@Test | ||
fun testSingle() = noLegacyJs { | ||
val single = "foo" | ||
assertJsonFormAndRestored( | ||
AnyValue.serializer(), | ||
AnyValue.Single(single), | ||
"\"$single\"" | ||
) | ||
} | ||
|
||
@Test | ||
fun testComplex() = noLegacyJs { | ||
val complexJson = """{"id":"1","name":"object"}""" | ||
assertJsonFormAndRestored( | ||
AnyValue.serializer(), | ||
AnyValue.Complex(mapOf("id" to "1", "name" to "object")), | ||
complexJson | ||
) | ||
} | ||
|
||
@Test | ||
fun testMulti() = noLegacyJs { | ||
val multiJson = """["list","of","strings"]""" | ||
assertJsonFormAndRestored(AnyValue.serializer(), AnyValue.Multi(listOf("list", "of", "strings")), multiJson) | ||
} | ||
} | ||
|
||
|
||
// From https://github.com/Kotlin/kotlinx.serialization/issues/2159 | ||
@Serializable(with = AnyValue.Companion.Serializer::class) | ||
sealed interface AnyValue { | ||
|
||
@JvmInline | ||
@Serializable | ||
value class Single(val value: String) : AnyValue | ||
|
||
@JvmInline | ||
@Serializable | ||
value class Multi(val values: List<String>) : AnyValue | ||
|
||
@JvmInline | ||
@Serializable | ||
value class Complex(val values: Map<String, String>) : AnyValue | ||
|
||
@JvmInline | ||
@Serializable | ||
value class Unknown(val value: JsonElement) : AnyValue | ||
|
||
companion object { | ||
object Serializer : JsonContentPolymorphicSerializer<AnyValue>(AnyValue::class) { | ||
|
||
override fun selectDeserializer(element: JsonElement): DeserializationStrategy<AnyValue> = | ||
when { | ||
element is JsonArray && element.all { it is JsonPrimitive && it.isString } -> Multi.serializer() | ||
element is JsonObject && element.values.all { it is JsonPrimitive && it.isString } -> Complex.serializer() | ||
element is JsonPrimitive && element.isString -> Single.serializer() | ||
else -> Unknown.serializer() | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters