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

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

View File

@ -4,19 +4,64 @@ import kotlinx.serialization.CompositeDecoder
import kotlinx.serialization.Decoder
import kotlinx.serialization.KSerializer
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) {
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 descriptor(name: String, block: SerialDescriptorBuilder.() -> Unit) = impl.pushDescriptor(
SerialDescriptorBuilder(SerialClassDescImpl(name)).apply(block).build()
)
fun build(): SerialDescriptor = impl
}

View File

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