Thread
#serialization
    r

    robgray

    3 years ago
    Hey all, I have a serializer class for integer backed enums. I'd like to handle de-serializing a case that doesn't exist (ex. 3) by returning null instead of throwing an exception. Is this possible?
    @kotlinx.serialization.Serializable(TestEnum.TestEnumSerializer::class)
        enum class TestEnum(val value: Int) {
            RED(0),
            GREEN(1),
            BLUE(2);
    
            @Serializer(forClass = TestEnum::class)
            companion object TestEnumSerializer : KSerializer<TestEnum> {
                private val map = values().associateBy(TestEnum::value)
    
                override val descriptor: SerialDescriptor
                    get() = StringDescriptor
    
                override fun deserialize(decoder: Decoder): TestEnum {
                    return map.getValue(decoder.decodeInt())
                }
    
                override fun serialize(encoder: Encoder, obj: TestEnum) {
                    encoder.encodeInt(obj.value)
                }
            }
        }
    Nikky

    Nikky

    3 years ago
    first of all you need to use
    TestEnum?
    and then you can use
    map.get(decoder.decodeInt()) ?: null
    i think
    r

    robgray

    3 years ago
    When I change it to optional i get this build error
    Can't serialize non-nullable field of type TestEnum with nullable serializer TestEnumSerializer
    turansky

    turansky

    3 years ago
    KSerializer<TestEnum>
    ->
    KSerializer<TestEnum?>
    r

    robgray

    3 years ago
    @kotlinx.serialization.Serializable(TestEnum.TestEnumSerializer::class)
        enum class TestEnum(val value: Int) {
            RED(0),
            GREEN(1),
            BLUE(2);
    
            @Serializer(forClass = TestEnum::class)
            companion object TestEnumSerializer : KSerializer<TestEnum?> {
                private val map = values().associateBy(TestEnum::value)
    
                override val descriptor: SerialDescriptor
                    get() = StringDescriptor
    
                override fun deserialize(decoder: Decoder): TestEnum? {
                    return map[decoder.decodeInt()]
                }
    
                override fun serialize(encoder: Encoder, obj: TestEnum?) {
                    obj?.value?.let { encoder.encodeInt(it) }
                }
            }
        }
    Codegen fails with an IllegalStateException - Cause: Can't serialize non-nullable field of type TestEnum with nullable serializer TestEnumSerializer
    Upgrading to kotlin ‘1.35.0’ fixed this, thanks everyone!