|
/* |
|
* This Source Code Form is subject to the terms of the Mozilla Public |
|
* License, v. 2.0. If a copy of the MPL was not distributed with this |
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. |
|
*/ |
|
|
|
package quest.laxla.khuzdul |
|
|
|
import kotlinx.serialization.ExperimentalSerializationApi |
|
import kotlinx.serialization.InternalSerializationApi |
|
import kotlinx.serialization.SerializationStrategy |
|
import kotlinx.serialization.descriptors.SerialDescriptor |
|
import kotlinx.serialization.encoding.CompositeEncoder |
|
import kotlinx.serialization.encoding.Encoder |
|
|
|
/** |
|
* @author @[email protected] |
|
* @author @[email protected] |
|
*/ |
|
public interface SerializerDelegator { |
|
@InternalSerializationApi |
|
public fun <T> determineEffectiveSerializer(serializer: SerializationStrategy<T>): SerializationStrategy<T> |
|
|
|
public companion object { |
|
public fun <T> SerializerDelegator.wrap(serializer: SerializationStrategy<T>): SerializationStrategy<T> = |
|
WrappingStrategy(delegate = serializer, delegator = this) |
|
} |
|
|
|
private class WrappingStrategy<T>( |
|
val delegate: SerializationStrategy<T>, |
|
val delegator: SerializerDelegator |
|
) : SerializationStrategy<T> { |
|
override val descriptor: SerialDescriptor |
|
get() = delegate.descriptor |
|
|
|
override fun serialize(encoder: Encoder, value: T) { |
|
delegate.serialize(WrappedEncoder(encoder, delegator), value) |
|
} |
|
} |
|
|
|
|
|
private class WrappedEncoder(val delegate: Encoder, val delegator: SerializerDelegator) : Encoder by delegate { |
|
@OptIn(InternalSerializationApi::class) |
|
override fun <T> encodeSerializableValue(serializer: SerializationStrategy<T>, value: T) = |
|
delegate.encodeSerializableValue(delegator.determineEffectiveSerializer(serializer), value) |
|
|
|
@OptIn(InternalSerializationApi::class) |
|
@ExperimentalSerializationApi |
|
override fun <T : Any> encodeNullableSerializableValue(serializer: SerializationStrategy<T>, value: T?) = |
|
delegate.encodeNullableSerializableValue(delegator.determineEffectiveSerializer(serializer), value) |
|
|
|
override fun beginStructure(descriptor: SerialDescriptor): CompositeEncoder = |
|
WrappedCompositeEncoder(delegate.beginStructure(descriptor), delegator) |
|
|
|
override fun beginCollection(descriptor: SerialDescriptor, collectionSize: Int): CompositeEncoder = |
|
WrappedCompositeEncoder(delegate.beginCollection(descriptor, collectionSize), delegator) |
|
} |
|
|
|
private class WrappedCompositeEncoder( |
|
val delegate: CompositeEncoder, |
|
val delegator: SerializerDelegator |
|
) : CompositeEncoder by delegate { |
|
@OptIn(InternalSerializationApi::class) |
|
override fun <T> encodeSerializableElement( |
|
descriptor: SerialDescriptor, |
|
index: Int, |
|
serializer: SerializationStrategy<T>, |
|
value: T |
|
) = delegate.encodeSerializableElement( |
|
descriptor = descriptor, |
|
index = index, |
|
serializer = delegator.determineEffectiveSerializer(serializer), |
|
value = value |
|
) |
|
|
|
@OptIn(InternalSerializationApi::class) |
|
@ExperimentalSerializationApi |
|
override fun <T : Any> encodeNullableSerializableElement( |
|
descriptor: SerialDescriptor, |
|
index: Int, |
|
serializer: SerializationStrategy<T>, |
|
value: T? |
|
) = delegate.encodeNullableSerializableElement( |
|
descriptor = descriptor, |
|
index = index, |
|
serializer = delegator.determineEffectiveSerializer(serializer), |
|
value = value |
|
) |
|
|
|
override fun encodeInlineElement(descriptor: SerialDescriptor, index: Int): Encoder = |
|
WrappedEncoder(delegate.encodeInlineElement(descriptor, index), delegator) |
|
} |
|
} |