Сериализация Kotlinx, избегайте сбоев на других типах данных - PullRequest
0 голосов
/ 04 октября 2019

Я использую внешний API в приложении, в то время как десериализация выполняется с помощью пакета Kotlinx Serialization, я сталкиваюсь с проблемами, когда результатом API является Array of Int для нескольких значений и примитив int для одного значения. Как я могу избежать сбоев в этом процессе. Существует ли лучший подход, позволяющий избежать сбоев или создания классов данных

ex:

import kotlinx.serialization.Serializable

@Serializable

data class Bookings (val slots: List<Int>)

, когда в слотах задано одно значение, API возвращает {slots: 1}, когда в слотах задано многократное значение, API возвращает { slots: [1,2,3,4]}

1 Ответ

1 голос
/ 04 октября 2019

Это можно сделать с помощью специального сериализатора:

import kotlinx.serialization.*
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonInput
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.int

@Serializable(with = BookingsSerializer::class)
data class Bookings(val slots: List<Int>)

@Serializer(forClass = Bookings::class)
object BookingsSerializer : KSerializer<Bookings> {
    override fun deserialize(decoder: Decoder): Bookings {
        val json = (decoder as JsonInput).decodeJson().jsonObject
        return Bookings(parseSlots(json))
    }

    private fun parseSlots(json: JsonObject): List<Int> {
        val slotsJson = json["slots"] ?: return emptyList()
        return try {
            slotsJson.jsonArray.content.map { it.int }
        } catch (e: Exception) {
            listOf(slotsJson.int)
        }
    }
}

@ImplicitReflectionSerializer
fun main() {
    val json = """{"slots": 1}"""
    val result = Json.parse<Bookings>(json)
    println(result) // prints Bookings(slots=[1])
}
...