-
Notifications
You must be signed in to change notification settings - Fork 628
/
Copy pathexample-json-31.kt
59 lines (51 loc) · 2.15 KB
/
example-json-31.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// This file was automatically generated from json.md by Knit tool. Do not edit.
package example.exampleJson31
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 = buildClassSerialDescriptor("Response") {
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))
}