mirror of
https://github.com/bitwarden/android.git
synced 2026-03-10 04:03:24 -05:00
[PM-19840] Migrate BaseEnumeratedIntSerializer to core module (#4975)
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
package com.bitwarden.core.data.serializer
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
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]. 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 className: String,
|
||||
private val values: Array<T>,
|
||||
private val default: T? = null,
|
||||
) : KSerializer<T> {
|
||||
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = PrimitiveSerialDescriptor(
|
||||
serialName = this::class.java.simpleName,
|
||||
kind = PrimitiveKind.INT,
|
||||
)
|
||||
|
||||
override fun deserialize(decoder: Decoder): T {
|
||||
val decodedValue = decoder.decodeInt().toString()
|
||||
return values.firstOrNull { it.serialNameAnnotation?.value == decodedValue }
|
||||
?: default
|
||||
?: throw IllegalArgumentException("Unknown value $decodedValue for $className")
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: T) {
|
||||
encoder.encodeInt(
|
||||
requireNotNull(
|
||||
value.serialNameAnnotation?.value?.toInt(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private val Enum<*>.serialNameAnnotation: SerialName?
|
||||
get() = javaClass.getDeclaredField(name).getAnnotation(SerialName::class.java)
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.bitwarden.core.data.serializer
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.encodeToJsonElement
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class BaseEnumeratedIntSerializerTest {
|
||||
private val json = Json
|
||||
|
||||
@Test
|
||||
fun `properly deserializes integers to enums`() {
|
||||
assertEquals(
|
||||
TestEnum.CASE_1,
|
||||
json.decodeFromString<TestEnum>(
|
||||
"""
|
||||
1
|
||||
""",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `properly serializes enums back to integers`() {
|
||||
assertEquals(
|
||||
json.parseToJsonElement(
|
||||
"""
|
||||
1
|
||||
""",
|
||||
),
|
||||
json.encodeToJsonElement(
|
||||
TestEnum.CASE_1,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `properly returns default value when unknown value is provided`() {
|
||||
assertEquals(
|
||||
TestEnum.UNKNOWN,
|
||||
json.decodeFromString<TestEnum>(
|
||||
"""
|
||||
-1
|
||||
""",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable(TestEnumSerializer::class)
|
||||
private enum class TestEnum {
|
||||
@SerialName("1")
|
||||
CASE_1,
|
||||
|
||||
@SerialName("2")
|
||||
CASE_2,
|
||||
|
||||
@SerialName("-1")
|
||||
UNKNOWN,
|
||||
}
|
||||
|
||||
private class TestEnumSerializer : BaseEnumeratedIntSerializer<TestEnum>(
|
||||
className = "TestEnum",
|
||||
values = TestEnum.entries.toTypedArray(),
|
||||
default = TestEnum.UNKNOWN,
|
||||
)
|
||||
Reference in New Issue
Block a user