[PM-14656] Add default value to BaseEnumeratedIntSerializer (#4272)

This commit is contained in:
Patrick Honkonen 2024-11-08 17:21:16 -05:00 committed by GitHub
parent 016d0f889c
commit 49642f5a1d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 38 additions and 6 deletions

View file

@ -10,11 +10,13 @@ import kotlinx.serialization.encoding.Encoder
/**
* Base [KSerializer] for mapping an [Enum] with possible values given by [values] to/from integer
* values, which should be specified using [SerialName].
* values, which should be specified using [SerialName]. If a [default] value is provided, it will
* be used when an unknown value is provided.
*/
@Suppress("UnnecessaryAbstractClass")
abstract class BaseEnumeratedIntSerializer<T : Enum<T>>(
private val values: Array<T>,
private val default: T? = null,
) : KSerializer<T> {
override val descriptor: SerialDescriptor
@ -25,7 +27,9 @@ abstract class BaseEnumeratedIntSerializer<T : Enum<T>>(
override fun deserialize(decoder: Decoder): T {
val decodedValue = decoder.decodeInt().toString()
return values.first { it.serialNameAnnotation?.value == decodedValue }
return values.firstOrNull { it.serialNameAnnotation?.value == decodedValue }
?: default
?: throw IllegalArgumentException("Unknown value $decodedValue")
}
override fun serialize(encoder: Encoder, value: T) {

View file

@ -81,8 +81,19 @@ enum class PolicyTypeJson {
*/
@SerialName("11")
ACTIVATE_AUTOFILL,
/**
* Represents an unknown policy type.
*
* This is used for forward compatibility to handle new policy types that the client doesn't yet
* understand.
*/
@SerialName("-1")
UNKNOWN,
}
@Keep
private class PolicyTypeSerializer :
BaseEnumeratedIntSerializer<PolicyTypeJson>(PolicyTypeJson.entries.toTypedArray())
private class PolicyTypeSerializer : BaseEnumeratedIntSerializer<PolicyTypeJson>(
values = PolicyTypeJson.entries.toTypedArray(),
default = PolicyTypeJson.UNKNOWN,
)

View file

@ -35,6 +35,18 @@ class BaseEnumeratedIntSerializerTest {
),
)
}
@Test
fun `properly returns default value when unknown value is provided`() {
assertEquals(
TestEnum.UNKNOWN,
json.decodeFromString<TestEnum>(
"""
-1
""",
),
)
}
}
@Serializable(TestEnumSerializer::class)
@ -44,7 +56,12 @@ private enum class TestEnum {
@SerialName("2")
CASE_2,
@SerialName("-1")
UNKNOWN,
}
private class TestEnumSerializer :
BaseEnumeratedIntSerializer<TestEnum>(values = TestEnum.entries.toTypedArray())
private class TestEnumSerializer : BaseEnumeratedIntSerializer<TestEnum>(
values = TestEnum.entries.toTypedArray(),
default = TestEnum.UNKNOWN,
)