New Meta serializer
This commit is contained in:
parent
810f79b9ed
commit
acfb070938
@ -27,6 +27,7 @@ class MetaSerializerTest {
|
||||
@Test
|
||||
fun testMetaSerialization() {
|
||||
val string = JSON_PRETTY.encodeToString(MetaSerializer, meta)
|
||||
println(string)
|
||||
val restored = JSON_PLAIN.decodeFromString(MetaSerializer, string)
|
||||
assertEquals(meta, restored)
|
||||
}
|
||||
@ -35,7 +36,7 @@ class MetaSerializerTest {
|
||||
@Test
|
||||
fun testCborSerialization() {
|
||||
val bytes = Cbor.encodeToByteArray(MetaSerializer, meta)
|
||||
println(bytes.contentToString())
|
||||
println(bytes.decodeToString())
|
||||
val restored = Cbor.decodeFromByteArray(MetaSerializer, bytes)
|
||||
assertEquals(meta, restored)
|
||||
}
|
||||
|
@ -28,8 +28,8 @@ public interface ObservableMeta : Meta {
|
||||
/**
|
||||
* Mutable meta representing object state
|
||||
*/
|
||||
@Serializable
|
||||
public class Config : AbstractMutableMeta<Config>(), ObservableMeta {
|
||||
@Serializable(Config.Companion::class)
|
||||
public class Config() : AbstractMutableMeta<Config>(), ObservableMeta {
|
||||
|
||||
private val listeners = HashSet<MetaListener>()
|
||||
|
||||
|
@ -4,14 +4,11 @@ import hep.dataforge.meta.Meta.Companion.VALUE_KEY
|
||||
import hep.dataforge.meta.MetaItem.NodeItem
|
||||
import hep.dataforge.meta.MetaItem.ValueItem
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.values.*
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.KSerializer
|
||||
import hep.dataforge.values.EnumValue
|
||||
import hep.dataforge.values.Null
|
||||
import hep.dataforge.values.Value
|
||||
import hep.dataforge.values.boolean
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Serializer
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
|
||||
@ -20,29 +17,17 @@ import kotlinx.serialization.json.Json
|
||||
* * a [ValueItem] (leaf)
|
||||
* * a [NodeItem] (node)
|
||||
*/
|
||||
@Serializable
|
||||
public sealed class MetaItem<out M : Meta> {
|
||||
@Serializable(MetaItemSerializer::class)
|
||||
public sealed class MetaItem<out M : Meta>() {
|
||||
|
||||
abstract override fun equals(other: Any?): Boolean
|
||||
|
||||
abstract override fun hashCode(): Int
|
||||
|
||||
@Serializable
|
||||
@Serializable(MetaItemSerializer::class)
|
||||
public class ValueItem(public val value: Value) : MetaItem<Nothing>() {
|
||||
override fun toString(): String = value.toString()
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@Serializer(ValueItem::class)
|
||||
public companion object : KSerializer<ValueItem> {
|
||||
override val descriptor: SerialDescriptor get() = ValueSerializer.descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): ValueItem = ValueItem(ValueSerializer.deserialize(decoder))
|
||||
|
||||
override fun serialize(encoder: Encoder, value: ValueItem) {
|
||||
ValueSerializer.serialize(encoder, value.value)
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return this.value == (other as? ValueItem)?.value
|
||||
}
|
||||
@ -52,23 +37,11 @@ public sealed class MetaItem<out M : Meta> {
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public class NodeItem<M : Meta>(@Serializable(MetaSerializer::class) public val node: M) : MetaItem<M>() {
|
||||
@Serializable(MetaItemSerializer::class)
|
||||
public class NodeItem<M : Meta>(public val node: M) : MetaItem<M>() {
|
||||
//Fixing serializer for node could cause class cast problems, but it should not since Meta descendants are not serializeable
|
||||
override fun toString(): String = node.toString()
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@Serializer(NodeItem::class)
|
||||
public companion object : KSerializer<NodeItem<out Meta>> {
|
||||
override val descriptor: SerialDescriptor get() = MetaSerializer.descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): NodeItem<*> = NodeItem(MetaSerializer.deserialize(decoder))
|
||||
|
||||
override fun serialize(encoder: Encoder, value: NodeItem<*>) {
|
||||
MetaSerializer.serialize(encoder, value.node)
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean = node == (other as? NodeItem<*>)?.node
|
||||
|
||||
override fun hashCode(): Int = node.hashCode()
|
||||
@ -112,7 +85,6 @@ public fun interface ItemProvider {
|
||||
*
|
||||
* * Same name siblings are supported via elements with the same [Name] but different queries
|
||||
*/
|
||||
@Serializable(MetaSerializer::class)
|
||||
public interface Meta : MetaRepr, ItemProvider {
|
||||
/**
|
||||
* Top level items of meta tree
|
||||
|
@ -1,17 +1,54 @@
|
||||
package hep.dataforge.meta
|
||||
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.values.ValueSerializer
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.InternalSerializationApi
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializer
|
||||
import kotlinx.serialization.builtins.MapSerializer
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlinx.serialization.descriptors.*
|
||||
import kotlinx.serialization.encoding.*
|
||||
import kotlinx.serialization.json.JsonDecoder
|
||||
import kotlinx.serialization.json.JsonEncoder
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
public object MetaItemSerializer : KSerializer<MetaItem<*>> {
|
||||
|
||||
@OptIn(InternalSerializationApi::class)
|
||||
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.meta.MetaItem") {
|
||||
element<Boolean>("isNode")
|
||||
element("content", buildSerialDescriptor("MetaItem.content", PolymorphicKind.SEALED))
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): MetaItem<*> {
|
||||
decoder.decodeStructure(descriptor) {
|
||||
//Force strict serialization order
|
||||
require(decodeElementIndex(descriptor) == 0) { "Node flag must be first item serialized" }
|
||||
val isNode = decodeBooleanElement(descriptor, 0)
|
||||
require(decodeElementIndex(descriptor) == 1) { "Missing MetaItem content" }
|
||||
val item = if (isNode) {
|
||||
decodeSerializableElement(descriptor,1, MetaSerializer).asMetaItem()
|
||||
} else {
|
||||
decodeSerializableElement(descriptor,1,ValueSerializer).asMetaItem()
|
||||
}
|
||||
require(decodeElementIndex(descriptor) == CompositeDecoder.DECODE_DONE){"Serialized MetaItem contains additional fields"}
|
||||
return item
|
||||
}
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: MetaItem<*>) {
|
||||
encoder.encodeStructure(descriptor) {
|
||||
encodeBooleanElement(descriptor, 0, value is MetaItem.NodeItem)
|
||||
when (value) {
|
||||
is MetaItem.ValueItem -> encodeSerializableElement(descriptor, 1, ValueSerializer, value.value)
|
||||
is MetaItem.NodeItem -> encodeSerializableElement(descriptor, 1, MetaSerializer, value.node)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialized for meta
|
||||
*/
|
||||
@ -19,9 +56,9 @@ import kotlinx.serialization.json.JsonObject
|
||||
@Serializer(Meta::class)
|
||||
public object MetaSerializer : KSerializer<Meta> {
|
||||
|
||||
private val mapSerializer = MapSerializer(
|
||||
NameToken.serializer(),
|
||||
MetaItem.serializer(MetaSerializer)
|
||||
private val mapSerializer: KSerializer<Map<NameToken, MetaItem<Meta>>> = MapSerializer(
|
||||
NameToken,
|
||||
MetaItemSerializer//MetaItem.serializer(MetaSerializer)
|
||||
)
|
||||
|
||||
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
||||
|
@ -19,7 +19,6 @@ public enum class ValueType {
|
||||
*
|
||||
* Value can represent a list of value objects.
|
||||
*/
|
||||
@Serializable(ValueSerializer::class)
|
||||
public interface Value {
|
||||
/**
|
||||
* Get raw value of this value
|
||||
|
Loading…
Reference in New Issue
Block a user