Added descriptors to custom serializers

This commit is contained in:
Alexander Nozik 2019-10-31 10:21:52 +03:00
parent 0ef0a43077
commit 6e98bc7408
3 changed files with 64 additions and 13 deletions

View File

@ -17,9 +17,9 @@ object ValueSerializer : KSerializer<Value> {
private val listSerializer by lazy { ArrayListSerializer(ValueSerializer) } private val listSerializer by lazy { ArrayListSerializer(ValueSerializer) }
override val descriptor: SerialDescriptor = descriptor("Value") { override val descriptor: SerialDescriptor = descriptor("Value") {
element("isList") boolean("isList")
element("valueType") enum<ValueType>("valueType")
element("value") element("value", PolymorphicClassDescriptor)
} }
private fun Decoder.decodeValue(): Value { private fun Decoder.decodeValue(): Value {
@ -68,10 +68,11 @@ object ValueSerializer : KSerializer<Value> {
@Serializer(MetaItem::class) @Serializer(MetaItem::class)
object MetaItemSerializer : KSerializer<MetaItem<*>> { object MetaItemSerializer : KSerializer<MetaItem<*>> {
override val descriptor: SerialDescriptor = descriptor("MetaItem") { override val descriptor: SerialDescriptor = descriptor("MetaItem") {
element("isNode") boolean("isNode")
element("value") element("value", PolymorphicClassDescriptor)
} }
override fun deserialize(decoder: Decoder): MetaItem<*> { override fun deserialize(decoder: Decoder): MetaItem<*> {
val isNode = decoder.decodeBoolean() val isNode = decoder.decodeBoolean()
return if (isNode) { return if (isNode) {

View File

@ -4,19 +4,64 @@ import kotlinx.serialization.CompositeDecoder
import kotlinx.serialization.Decoder import kotlinx.serialization.Decoder
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialDescriptor import kotlinx.serialization.SerialDescriptor
import kotlinx.serialization.internal.SerialClassDescImpl import kotlinx.serialization.internal.*
/**
* A convenience builder for serial descriptors
*/
inline class SerialDescriptorBuilder(private val impl: SerialClassDescImpl) { inline class SerialDescriptorBuilder(private val impl: SerialClassDescImpl) {
fun element(name: String, isOptional: Boolean = false) = impl.addElement(name, isOptional) fun element(
name: String,
descriptor: SerialDescriptor,
isOptional: Boolean = false,
vararg annotations: Annotation
) {
impl.addElement(name, isOptional)
impl.pushDescriptor(descriptor)
annotations.forEach {
impl.pushAnnotation(it)
}
}
fun annotation(a: Annotation) = impl.pushAnnotation(a) fun element(
name: String,
isOptional: Boolean = false,
vararg annotations: Annotation,
block: SerialDescriptorBuilder.() -> Unit
) {
impl.addElement(name, isOptional)
impl.pushDescriptor(SerialDescriptorBuilder(SerialClassDescImpl(name)).apply(block).build())
annotations.forEach {
impl.pushAnnotation(it)
}
}
fun boolean(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, BooleanDescriptor, isOptional, *annotations)
fun string(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, StringDescriptor, isOptional, *annotations)
fun int(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, IntDescriptor, isOptional, *annotations)
fun double(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, DoubleDescriptor, isOptional, *annotations)
fun float(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, FloatDescriptor, isOptional, *annotations)
fun long(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, LongDescriptor, isOptional, *annotations)
fun doubleArray(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, DoubleArraySerializer.descriptor, isOptional, *annotations)
inline fun <reified E: Enum<E>> enum(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, EnumSerializer(E::class).descriptor, isOptional, *annotations)
fun classAnnotation(a: Annotation) = impl.pushClassAnnotation(a) fun classAnnotation(a: Annotation) = impl.pushClassAnnotation(a)
fun descriptor(name: String, block: SerialDescriptorBuilder.() -> Unit) = impl.pushDescriptor(
SerialDescriptorBuilder(SerialClassDescImpl(name)).apply(block).build()
)
fun build(): SerialDescriptor = impl fun build(): SerialDescriptor = impl
} }

View File

@ -51,4 +51,9 @@ class MetaSerializerTest {
val restored = Json.plain.parse(NameSerializer, string) val restored = Json.plain.parse(NameSerializer, string)
assertEquals(restored, name) assertEquals(restored, name)
} }
@Test
fun testMetaItemDescriptor(){
val descriptor = MetaItemSerializer.descriptor.getElementDescriptor(0)
}
} }