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