[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 * 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") @Suppress("UnnecessaryAbstractClass")
abstract class BaseEnumeratedIntSerializer<T : Enum<T>>( abstract class BaseEnumeratedIntSerializer<T : Enum<T>>(
private val values: Array<T>, private val values: Array<T>,
private val default: T? = null,
) : KSerializer<T> { ) : KSerializer<T> {
override val descriptor: SerialDescriptor override val descriptor: SerialDescriptor
@ -25,7 +27,9 @@ abstract class BaseEnumeratedIntSerializer<T : Enum<T>>(
override fun deserialize(decoder: Decoder): T { override fun deserialize(decoder: Decoder): T {
val decodedValue = decoder.decodeInt().toString() 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) { override fun serialize(encoder: Encoder, value: T) {

View file

@ -81,8 +81,19 @@ enum class PolicyTypeJson {
*/ */
@SerialName("11") @SerialName("11")
ACTIVATE_AUTOFILL, 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 @Keep
private class PolicyTypeSerializer : private class PolicyTypeSerializer : BaseEnumeratedIntSerializer<PolicyTypeJson>(
BaseEnumeratedIntSerializer<PolicyTypeJson>(PolicyTypeJson.entries.toTypedArray()) 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) @Serializable(TestEnumSerializer::class)
@ -44,7 +56,12 @@ private enum class TestEnum {
@SerialName("2") @SerialName("2")
CASE_2, CASE_2,
@SerialName("-1")
UNKNOWN,
} }
private class TestEnumSerializer : private class TestEnumSerializer : BaseEnumeratedIntSerializer<TestEnum>(
BaseEnumeratedIntSerializer<TestEnum>(values = TestEnum.entries.toTypedArray()) values = TestEnum.entries.toTypedArray(),
default = TestEnum.UNKNOWN,
)