LoginSignup
1
1

More than 3 years have passed since last update.

KotlinのEnum の JSON シリアライズ結果をカスタマイズする

Last updated at Posted at 2019-12-03

kotlinx.serialization

CommonEnumIntSerializer.kt
open class CommonEnumIntSerializer<T>(
    val serialName: String,
    val choices: Array<T>,
    val choicesNumbers: Array<Int>
) :
    KSerializer<T> {

    override val descriptor: EnumDescriptor = EnumDescriptor(serialName, choicesNumbers.map { it.toString() }.toTypedArray())

    init {
        require(choicesNumbers.size == choices.size) { "There must be exactly one serial number for every enum constant." }
        require(choicesNumbers.distinct().size == choicesNumbers.size) { "There must be no duplicates of serial numbers." }
    }

    final override fun serialize(encoder: Encoder, obj: T) {
        val index = choices.indexOf(obj)
            .also { check(it != -1) { "$obj is not a valid enum $serialName, choices are $choices" } }
        encoder.encodeInt(choicesNumbers[index])
    }

    final override fun deserialize(decoder: Decoder): T {
        val serialNumber = decoder.decodeInt()
        val index = choicesNumbers.indexOf(serialNumber)
        check(index != -1) { "$serialNumber is not a valid serial value of $serialName, choices are $choicesNumbers" }
        check(index in choices.indices)
        { "$index is not among valid $serialName choices, choices size is ${choices.size}" }
        return choices[index]
    }
}
SerialEnum.kt
interface SerialEnum {
    val serialNumber: Int?
}
fun <T> Array<T>.serial() where T : SerialEnum, T : Enum<T> = this.map { it.serialNumber ?: it.ordinal }.toTypedArray()
TestEnum.kt
object TestSerializer :
        CommonEnumIntSerializer<TestEnum>("TestEnum", TestEnum.values(), TestEnum.values().serial())

@Serializable(with = TestSerializer::class)
enum class TestEnum(override val serialNumber: Int? = null) : SerialEnum {
    Foo(123), // Will be serialized to 123
    AnotherConstant // Will be serialized to 1
}

Jackson

@JsonValue アノテーションを使う
https://qiita.com/t-otsuka/items/ef7cd9cac84b2c1915c1

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1