Kotlin 1.3.70 がリリースされました https://blog.jetbrains.com/kotlin/2020/03/kotlin-1-3-70-released/
kotlinx.serialization を 0.20.0 へアップデートする必要がありますが、いくつかコードの修正が必要になります。
- kotlinx.serialization 0.20.0 の変更点はこちら
SerialDescriptor の変更
kotlinx.serialization 0.14.0 までは、カスタムシリアライザを実装するときは以下のような形式でした。
// Klock を使っています
@Serializer(DateTimeTz::class)
class KlockDateTimeTzIso8601Serializer : KSerializer<DateTimeTz> {
companion object {
fun formatter(): DateFormat {
return DateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
}
}
private val format: DateFormat = formatter()
override val descriptor: SerialDescriptor = StringDescriptor.withName("DateTimeTz")
override fun serialize(encoder: Encoder, obj: DateTimeTz) {
encoder.encodeString(format.format(obj))
}
override fun deserialize(decoder: Decoder): DateTimeTz {
return format.parse(decoder.decodeString())
}
}
これは以下のビルドエラーとなります。
Using 'withName(String): SerialDescriptor' is an error. Deprecated in the favour of PrimitiveDescriptor factory function
StringDescriptor が非推奨になっているため、descriptor を PrimitiveDescriptor 形式へ書き換えます。
override val descriptor: SerialDescriptor = PrimitiveDescriptor("DateTimeTz", PrimitiveKind.STRING)
PrimitiveDescriptor は https://github.com/Kotlin/kotlinx.serialization/blob/146a0d08ed87a97cf5435a89fcafd3aa639c106e/runtime/commonMain/src/kotlinx/serialization/SerialDescriptorBuilder.kt#L60 に実装されています。
PrimitiveDescriptor はシリアライズに encoder.encodeString
decoder.decodeString
を使用している場合に PrimitiveKind.STRING を指定します。
encoder.encodeLong
decoder.decodeLong
を使っている場合は PrimitiveKind.LONG
です。
https://github.com/Kotlin/kotlinx.serialization/blob/146a0d08ed87a97cf5435a89fcafd3aa639c106e/runtime/commonMain/src/kotlinx/serialization/SerialKinds.kt#L54 こちらにすべての Primitive 型が定義されています。
public object BOOLEAN : PrimitiveKind()
public object BYTE : PrimitiveKind()
public object CHAR : PrimitiveKind()
public object SHORT : PrimitiveKind()
public object INT : PrimitiveKind()
public object LONG : PrimitiveKind()
public object FLOAT : PrimitiveKind()
public object DOUBLE : PrimitiveKind()
public object STRING : PrimitiveKind()
シリアライズ時に複数のデータをエンコード・デコードする場合は PrimitiveDescriptor ではなく、 SerialDescriptor を使用し、保持するデータごとにキーを指定します。
* // Descriptor for such class: |
* SerialDescriptor("my.package.Data") { |
* // intField is deliberately ignored by serializer -- not present in the descriptor as well |
* element<Long>("_longField") // longField is named as _longField |
* element("stringField", listDescriptor<String>()) |
* }
builtins package への置き換え
bultins package へ移動した機能があります。
import kotlinx.serialization.list
MyClass.serializer().list
// -> Using 'list: KSerializer<List<T>>' is an error. Deprecated in the favour of the same extension from builtins package
↓
import kotlinx.serialization.builtins.list
MyClass.serializer().list
import kotlinx.serialization.internal.StringSerializer
StringSerializer()
// -> Using 'StringSerializer' is an error. Deprecated in the favour of String.serializer() extension
↓
import kotlinx.serialization.builtins.serializer
String.serializer()
Json.plain, Json.nonstrict ルールの置き換え
Json.plain, Json.nonstritc などの Json パーサー設定も非推奨となりました。
Json パーサールールが細分化されているため、 JsonConfiguration から設定しましょう。
Json.nonstrict 設定は https://github.com/Kotlin/kotlinx.serialization/blob/146a0d08ed87a97cf5435a89fcafd3aa639c106e/runtime/commonMain/src/kotlinx/serialization/json/Json.kt#L193 がもとの設定です。
public val nonstrict = Json(
JsonConfiguration(
isLenient = true,
ignoreUnknownKeys = true,
serializeSpecialFloatingPointValues = true,
useArrayPolymorphism = true
)
)
これを参考に、以下のように書き換えます。
import kotlinx.serialization.json.Json
Json.nonstrict
// -> 'nonstrict: Json' is deprecated. Top-level JSON instances are deprecated for removal in the favour of user-configured one. You can either use a Json top-level object, configure your own instance via 'Json {}' builder-like constructor, 'Json(JsonConfiguration)' constructor or by tweaking stable configuration 'Json(JsonConfiguration.Stable.copy(prettyPrint = true))'
↓
Json {
isLenient = true
ignoreUnknownKeys = true
serializeSpecialFloatingPointValues = true
useArrayPolymorphism = true
}
ただし、これでは kotlinx.serialization のバージョンアップ時にデフォルトの Json 設定が変更されてしまうと、その影響を受けてしまいます。
バージョンアップの影響を受けないようにするには JsonConfiguration.Stable を使います。
Json(JsonConfiguration.Stable.copy(
ignoreUnknownKeys = true,
isLenient = true,
serializeSpecialFloatingPointValues = true,
useArrayPolymorphism = true
))