summaryrefslogtreecommitdiff
path: root/runtime/common/src/main/kotlin/kotlinx/serialization/json/JsonOutput.kt
blob: 25f69262167e2dcadce42ea8d9e10877cde4325a (plain)
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
/*
 * Copyright 2017-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package kotlinx.serialization.json

import kotlinx.serialization.*

/**
 * Encoder used by [Json] during serialization.
 * This interface can be used to inject desired behaviour into a serialization process of [Json].
 *
 * Typical example of the usage:
 * ```
 * // Class representing Either<Left|Right>
 * sealed class DummyEither {
 *   data class Left(val errorMsg: String) : DummyEither()
 *   data class Right(val data: Payload) : DummyEither()
 * }
 *
 * // Serializer injects custom behaviour by inspecting object content and writing
 * object EitherSerializer : KSerializer<DummyEither> {
 *   override val descriptor: SerialDescriptor = SerialClassDescImpl("DummyEither")
 *
 *   override fun deserialize(decoder: Decoder): DummyEither {
 *     val input = decoder as? JsonInput ?: throw SerializationException("This class can be loaded only by Json")
 *     val tree = input.decodeJson() as? JsonObject ?: throw SerializationException("Expected JsonObject")
 *     if ("error" in tree) return DummyEither.Left(tree.getPrimitive("error").content)
 *     return DummyEither.Right(input.json.decodeJson(tree, Payload.serializer()))
 *   }
 *
 *   override fun serialize(encoder: Encoder, obj: DummyEither) {
 *     val output = encoder as? JsonOutput ?: throw SerializationException("This class can be saved only by Json")
 *     val tree = when (obj) {
 *       is DummyEither.Left -> JsonObject(mapOf("error" to JsonLiteral(obj.errorMsg)))
 *       is DummyEither.Right -> output.json.toJson(obj.data, Payload.serializer())
 *     }
 *
 *     output.encodeJson(tree)
 *   }
 * }
 * ```
 */
public interface JsonOutput: Encoder, CompositeEncoder {
    /**
     * An instance of the current [Json].
     */
    public val json: Json

    /**
     * Appends given [element] to the output.
     */
    public fun encodeJson(element: JsonElement)
}