kotlinx.serialization
- 文字列に変換するなら
@SerialName
アノテーションを使う - 数値に変換するなら custom serializer を実装する
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