diff options
Diffstat (limited to 'guide/example/example-json-27.kt')
-rw-r--r-- | guide/example/example-json-27.kt | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/guide/example/example-json-27.kt b/guide/example/example-json-27.kt new file mode 100644 index 00000000..5905733a --- /dev/null +++ b/guide/example/example-json-27.kt @@ -0,0 +1,59 @@ +// This file was automatically generated from json.md by Knit tool. Do not edit. +package example.exampleJson27 + +import kotlinx.serialization.* +import kotlinx.serialization.json.* + +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* + +@Serializable(with = ResponseSerializer::class) +sealed class Response<out T> { + data class Ok<out T>(val data: T) : Response<T>() + data class Error(val message: String) : Response<Nothing>() +} + +class ResponseSerializer<T>(private val dataSerializer: KSerializer<T>) : KSerializer<Response<T>> { + override val descriptor: SerialDescriptor = buildSerialDescriptor("Response", PolymorphicKind.SEALED) { + element("Ok", dataSerializer.descriptor) + element("Error", buildClassSerialDescriptor("Error") { + element<String>("message") + }) + } + + override fun deserialize(decoder: Decoder): Response<T> { + // Decoder -> JsonDecoder + require(decoder is JsonDecoder) // this class can be decoded only by Json + // JsonDecoder -> JsonElement + val element = decoder.decodeJsonElement() + // JsonElement -> value + if (element is JsonObject && "error" in element) + return Response.Error(element["error"]!!.jsonPrimitive.content) + return Response.Ok(decoder.json.decodeFromJsonElement(dataSerializer, element)) + } + + override fun serialize(encoder: Encoder, value: Response<T>) { + // Encoder -> JsonEncoder + require(encoder is JsonEncoder) // This class can be encoded only by Json + // value -> JsonElement + val element = when (value) { + is Response.Ok -> encoder.json.encodeToJsonElement(dataSerializer, value.data) + is Response.Error -> buildJsonObject { put("error", value.message) } + } + // JsonElement -> JsonEncoder + encoder.encodeJsonElement(element) + } +} + +@Serializable +data class Project(val name: String) + +fun main() { + val responses = listOf( + Response.Ok(Project("kotlinx.serialization")), + Response.Error("Not found") + ) + val string = Json.encodeToString(responses) + println(string) + println(Json.decodeFromString<List<Response<Project>>>(string)) +} |