xref: /aosp_15_r20/external/kotlinx.serialization/guide/example/example-json-27.kt (revision 57b5a4a64c534cf7f27ac9427ceab07f3d8ed3d8)
1 // This file was automatically generated from json.md by Knit tool. Do not edit.
2 package example.exampleJson27
3 
4 import kotlinx.serialization.*
5 import kotlinx.serialization.json.*
6 
7 import kotlinx.serialization.descriptors.*
8 import kotlinx.serialization.encoding.*
9 
10 @Serializable(with = ResponseSerializer::class)
11 sealed class Response<out T> {
12     data class Ok<out T>(val data: T) : Response<T>()
13     data class Error(val message: String) : Response<Nothing>()
14 }
15 
16 class ResponseSerializer<T>(private val dataSerializer: KSerializer<T>) : KSerializer<Response<T>> {
<lambda>null17     override val descriptor: SerialDescriptor = buildSerialDescriptor("Response", PolymorphicKind.SEALED) {
18         element("Ok", dataSerializer.descriptor)
19         element("Error", buildClassSerialDescriptor("Error") {
20           element<String>("message")
21         })
22     }
23 
deserializenull24     override fun deserialize(decoder: Decoder): Response<T> {
25         // Decoder -> JsonDecoder
26         require(decoder is JsonDecoder) // this class can be decoded only by Json
27         // JsonDecoder -> JsonElement
28         val element = decoder.decodeJsonElement()
29         // JsonElement -> value
30         if (element is JsonObject && "error" in element)
31             return Response.Error(element["error"]!!.jsonPrimitive.content)
32         return Response.Ok(decoder.json.decodeFromJsonElement(dataSerializer, element))
33     }
34 
serializenull35     override fun serialize(encoder: Encoder, value: Response<T>) {
36         // Encoder -> JsonEncoder
37         require(encoder is JsonEncoder) // This class can be encoded only by Json
38         // value -> JsonElement
39         val element = when (value) {
40             is Response.Ok -> encoder.json.encodeToJsonElement(dataSerializer, value.data)
41             is Response.Error -> buildJsonObject { put("error", value.message) }
42         }
43         // JsonElement -> JsonEncoder
44         encoder.encodeJsonElement(element)
45     }
46 }
47 
48 @Serializable
49 data class Project(val name: String)
50 
mainnull51 fun main() {
52     val responses = listOf(
53         Response.Ok(Project("kotlinx.serialization")),
54         Response.Error("Not found")
55     )
56     val string = Json.encodeToString(responses)
57     println(string)
58     println(Json.decodeFromString<List<Response<Project>>>(string))
59 }
60