summaryrefslogtreecommitdiff
path: root/guide/example/example-json-27.kt
diff options
context:
space:
mode:
Diffstat (limited to 'guide/example/example-json-27.kt')
-rw-r--r--guide/example/example-json-27.kt59
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))
+}