summaryrefslogtreecommitdiff
path: root/runtime/commonMain/src/kotlinx/serialization/modules/SerialModuleExtensions.kt
blob: de102588e9194633a5ec85e12856d417614e1a8a (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
55
56
57
58
59
60
61
62
63
64
65
/*
 * Copyright 2017-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

@file:Suppress("RedundantVisibilityModifier")

package kotlinx.serialization.modules

import kotlinx.serialization.*
import kotlin.reflect.KClass

/**
 * Returns a dependent serializer associated with a given reified type.
 */
public inline fun <reified T: Any> SerialModule.getContextual(): KSerializer<T>? = getContextual(T::class)

/**
 * Returns a serializer associated with KClass of the given [value].
 */
@Suppress("UNCHECKED_CAST")
public fun <T: Any> SerialModule.getContextual(value: T): KSerializer<T>? {
    val klass = value::class
    return getContextual(klass) as? KSerializer<T>
}

@ImplicitReflectionSerializer
public fun <T: Any> SerialModule.getContextualOrDefault(klass: KClass<T>): KSerializer<T> = getContextual(klass) ?: klass.serializer()

@Suppress("UNCHECKED_CAST")
@ImplicitReflectionSerializer
public fun <T: Any> SerialModule.getContextualOrDefault(value: T): KSerializer<T> = getContextual(value) ?: value::class.serializer() as KSerializer<T>

/**
 * Returns a combination of two serial modules
 *
 * If some serializer present in both modules, an [SerializerAlreadyRegisteredException] is thrown.
 * To overwrite serializers, use [SerialModule.overwriteWith] function.
 */
public operator fun SerialModule.plus(other: SerialModule): SerialModule = SerializersModule {
    include(this@plus)
    include(other)
}

/**
 * Returns a combination of two serial modules
 *
 * If some serializers present in both modules, result module
 * will contain serializer from [other] module.
 */
public infix fun SerialModule.overwriteWith(other: SerialModule): SerialModule = SerializersModule {
    include(this@overwriteWith)
    other.dumpTo(object : SerialModuleCollector {
        override fun <T : Any> contextual(kClass: KClass<T>, serializer: KSerializer<T>) {
            impl.registerSerializer(kClass, serializer, allowOverwrite = true)
        }

        override fun <Base : Any, Sub : Base> polymorphic(
            baseClass: KClass<Base>,
            actualClass: KClass<Sub>,
            actualSerializer: KSerializer<Sub>
        ) {
            impl.registerPolymorphicSerializer(baseClass, actualClass, actualSerializer, allowOverwrite = true)
        }
    })
}