Simplify Scheme even more. Add serialization
This commit is contained in:
parent
14455c2b2b
commit
679175391a
@ -4,7 +4,7 @@ plugins {
|
||||
|
||||
allprojects {
|
||||
group = "space.kscience"
|
||||
version = "0.5.0"
|
||||
version = "0.5.0-dev-2"
|
||||
}
|
||||
|
||||
subprojects {
|
||||
|
@ -169,7 +169,9 @@ public final class space/kscience/dataforge/meta/MetaBase$Companion {
|
||||
}
|
||||
|
||||
public final class space/kscience/dataforge/meta/MetaBuilder : space/kscience/dataforge/meta/AbstractMutableMeta {
|
||||
public static final field Companion Lspace/kscience/dataforge/meta/MetaBuilder$Companion;
|
||||
public fun <init> ()V
|
||||
public synthetic fun <init> (ILjava/util/Map;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V
|
||||
public synthetic fun empty$dataforge_meta ()Lspace/kscience/dataforge/meta/MutableMeta;
|
||||
public final fun put (Ljava/lang/String;Ljava/lang/Boolean;)V
|
||||
public final fun put (Ljava/lang/String;Ljava/lang/Enum;)V
|
||||
@ -198,6 +200,22 @@ public final class space/kscience/dataforge/meta/MetaBuilder : space/kscience/da
|
||||
public synthetic fun wrapNode (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/MutableMeta;
|
||||
}
|
||||
|
||||
public final class space/kscience/dataforge/meta/MetaBuilder$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
|
||||
public static final field INSTANCE Lspace/kscience/dataforge/meta/MetaBuilder$$serializer;
|
||||
public static final synthetic field descriptor Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||
public fun childSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/dataforge/meta/MetaBuilder;
|
||||
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/dataforge/meta/MetaBuilder;)V
|
||||
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
|
||||
}
|
||||
|
||||
public final class space/kscience/dataforge/meta/MetaBuilder$Companion {
|
||||
public final fun serializer ()Lkotlinx/serialization/KSerializer;
|
||||
}
|
||||
|
||||
public final class space/kscience/dataforge/meta/MetaBuilderKt {
|
||||
public static final fun Meta (Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/MetaBuilder;
|
||||
public static final fun toMutableMeta (Lspace/kscience/dataforge/meta/Meta;)Lspace/kscience/dataforge/meta/MetaBuilder;
|
||||
@ -364,6 +382,15 @@ public final class space/kscience/dataforge/meta/MutableItemProviderKt {
|
||||
public static final fun withDefault (Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/ItemProvider;)Lspace/kscience/dataforge/meta/MutableItemProvider;
|
||||
}
|
||||
|
||||
public final class space/kscience/dataforge/meta/MutableItemProviderSerializer : kotlinx/serialization/KSerializer {
|
||||
public fun <init> ()V
|
||||
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
|
||||
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lspace/kscience/dataforge/meta/MutableItemProvider;
|
||||
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
|
||||
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
|
||||
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lspace/kscience/dataforge/meta/MutableItemProvider;)V
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/dataforge/meta/MutableMeta : space/kscience/dataforge/meta/MutableItemProvider, space/kscience/dataforge/meta/TypedMeta {
|
||||
public abstract fun getItems ()Ljava/util/Map;
|
||||
}
|
||||
@ -410,10 +437,8 @@ public abstract interface class space/kscience/dataforge/meta/ReadOnlySpecificat
|
||||
|
||||
public class space/kscience/dataforge/meta/Scheme : space/kscience/dataforge/meta/MetaRepr, space/kscience/dataforge/meta/ObservableItemProvider, space/kscience/dataforge/meta/descriptors/Described {
|
||||
public fun <init> ()V
|
||||
public fun <init> (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;Lspace/kscience/dataforge/meta/ItemProvider;)V
|
||||
public synthetic fun <init> (Lspace/kscience/dataforge/meta/ObservableItemProvider;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;Lspace/kscience/dataforge/meta/ItemProvider;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
protected fun getDefaultItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
|
||||
public fun getDefaultLayer ()Lspace/kscience/dataforge/meta/Meta;
|
||||
public fun <init> (Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)V
|
||||
public synthetic fun <init> (Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
|
||||
public synthetic fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/ItemDescriptor;
|
||||
public final fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;
|
||||
public fun getItem (Lspace/kscience/dataforge/names/Name;)Lspace/kscience/dataforge/meta/TypedMetaItem;
|
||||
@ -430,8 +455,8 @@ public final class space/kscience/dataforge/meta/SchemeKt {
|
||||
public static final fun invoke (Lspace/kscience/dataforge/meta/Scheme;Lkotlin/jvm/functions/Function1;)Lspace/kscience/dataforge/meta/Scheme;
|
||||
public static final fun isEmpty (Lspace/kscience/dataforge/meta/Scheme;)Z
|
||||
public static final fun retarget (Lspace/kscience/dataforge/meta/Scheme;Lspace/kscience/dataforge/meta/MutableItemProvider;)Lspace/kscience/dataforge/meta/Scheme;
|
||||
public static final fun wrap (Lspace/kscience/dataforge/meta/Specification;Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/ItemProvider;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;)Lspace/kscience/dataforge/meta/Scheme;
|
||||
public static synthetic fun wrap$default (Lspace/kscience/dataforge/meta/Specification;Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/ItemProvider;Lspace/kscience/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Scheme;
|
||||
public static final fun wrap (Lspace/kscience/dataforge/meta/Specification;Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/ItemProvider;)Lspace/kscience/dataforge/meta/Scheme;
|
||||
public static synthetic fun wrap$default (Lspace/kscience/dataforge/meta/Specification;Lspace/kscience/dataforge/meta/MutableItemProvider;Lspace/kscience/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lspace/kscience/dataforge/meta/Scheme;
|
||||
}
|
||||
|
||||
public class space/kscience/dataforge/meta/SchemeSpec : space/kscience/dataforge/meta/Specification, space/kscience/dataforge/meta/descriptors/Described {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package space.kscience.dataforge.meta
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.dataforge.misc.DFBuilder
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.NameToken
|
||||
@ -13,6 +14,7 @@ import kotlin.jvm.JvmName
|
||||
* DSL builder for meta. Is not intended to store mutable state
|
||||
*/
|
||||
@DFBuilder
|
||||
@Serializable
|
||||
public class MetaBuilder : AbstractMutableMeta<MetaBuilder>() {
|
||||
override val children: MutableMap<NameToken, TypedMetaItem<MetaBuilder>> = LinkedHashMap()
|
||||
|
||||
|
@ -1,12 +1,35 @@
|
||||
package space.kscience.dataforge.meta
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import space.kscience.dataforge.names.*
|
||||
import space.kscience.dataforge.values.Value
|
||||
|
||||
@Serializable(MutableItemProviderSerializer::class)
|
||||
public interface MutableItemProvider : ItemProvider {
|
||||
public fun setItem(name: Name, item: MetaItem?)
|
||||
}
|
||||
|
||||
/**
|
||||
* A serializer form [MutableItemProvider]
|
||||
*/
|
||||
public class MutableItemProviderSerializer : KSerializer<MutableItemProvider> {
|
||||
override val descriptor: SerialDescriptor = MetaSerializer.descriptor
|
||||
|
||||
|
||||
override fun deserialize(decoder: Decoder): MutableItemProvider {
|
||||
val meta = decoder.decodeSerializableValue(MetaSerializer)
|
||||
return (meta as? MetaBuilder) ?: meta.toMutableMeta()
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: MutableItemProvider) {
|
||||
encoder.encodeSerializableValue(MetaSerializer, value.rootItem?.node ?: Meta.EMPTY)
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun MutableItemProvider.set(name: Name, item: MetaItem?): Unit = setItem(name, item)
|
||||
|
||||
public operator fun MutableItemProvider.set(name: Name, value: Value?): Unit = set(name, value?.asMetaItem())
|
||||
|
@ -5,8 +5,6 @@ import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||
import space.kscience.dataforge.meta.descriptors.get
|
||||
import space.kscience.dataforge.meta.descriptors.validateItem
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.NameToken
|
||||
import space.kscience.dataforge.names.asName
|
||||
import kotlin.jvm.Synchronized
|
||||
|
||||
/**
|
||||
@ -15,8 +13,7 @@ import kotlin.jvm.Synchronized
|
||||
*/
|
||||
public open class Scheme(
|
||||
private var items: ObservableItemProvider = ObservableMeta(),
|
||||
final override var descriptor: NodeDescriptor? = null,
|
||||
private var default: ItemProvider? = null
|
||||
final override var descriptor: NodeDescriptor? = null
|
||||
) : Described, MetaRepr, ObservableItemProvider {
|
||||
|
||||
/**
|
||||
@ -38,24 +35,15 @@ public open class Scheme(
|
||||
|
||||
internal fun wrap(
|
||||
items: MutableItemProvider,
|
||||
default: ItemProvider? = null,
|
||||
descriptor: NodeDescriptor? = null,
|
||||
preserveDefault: Boolean = false
|
||||
) {
|
||||
//use properties in the init block as default
|
||||
this.default = this.items.withDefault(default)
|
||||
//reset values, defaults are already saved
|
||||
this.items = items.asObservable()
|
||||
this.descriptor = descriptor
|
||||
}
|
||||
|
||||
protected open fun getDefaultItem(name: Name): MetaItem? {
|
||||
return default?.get(name) ?: descriptor?.get(name)?.defaultValue
|
||||
this.items = if (preserveDefault) items.withDefault(this.items).asObservable() else items.asObservable()
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a property with default
|
||||
*/
|
||||
override fun getItem(name: Name): MetaItem? = items[name] ?: getDefaultItem(name)
|
||||
override fun getItem(name: Name): MetaItem? = items[name] ?: descriptor?.get(name)?.defaultValue
|
||||
|
||||
/**
|
||||
* Check if property with given [name] could be assigned to [item]
|
||||
@ -70,34 +58,16 @@ public open class Scheme(
|
||||
*/
|
||||
override fun setItem(name: Name, item: MetaItem?) {
|
||||
val oldItem = items[name]
|
||||
if (oldItem != item) {
|
||||
if (validateItem(name, item)) {
|
||||
items[name] = item
|
||||
} else {
|
||||
error("Validation failed for property $name with value $item")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provide a default layer which returns items from [default] and falls back to descriptor
|
||||
* values if default value is unavailable.
|
||||
* Values from [default] completely replace
|
||||
*/
|
||||
public open val defaultLayer: Meta
|
||||
get() = object : MetaBase() {
|
||||
override val items: Map<NameToken, MetaItem> = buildMap {
|
||||
descriptor?.items?.forEach { (key, itemDescriptor) ->
|
||||
val token = NameToken(key)
|
||||
val name = token.asName()
|
||||
val item = default?.get(name) ?: itemDescriptor.defaultValue
|
||||
if (item != null) {
|
||||
put(token, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun toMeta(): Laminate = Laminate(items.rootNode, defaultLayer)
|
||||
override fun toMeta(): Laminate = Laminate(items.rootNode, descriptor?.defaultMeta)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,23 +75,13 @@ public open class Scheme(
|
||||
*/
|
||||
public fun Scheme.isEmpty(): Boolean = rootItem == null
|
||||
|
||||
/**
|
||||
* Create a new empty [Scheme] object (including defaults) and inflate it around existing [MutableItemProvider].
|
||||
* Items already present in the scheme are used as defaults.
|
||||
*/
|
||||
public fun <T : Scheme, S : Specification<T>> S.wrap(
|
||||
items: MutableItemProvider,
|
||||
default: ItemProvider? = null,
|
||||
descriptor: NodeDescriptor? = null,
|
||||
): T = empty().apply {
|
||||
wrap(items, default, descriptor)
|
||||
}
|
||||
|
||||
/**
|
||||
* Relocate scheme target onto given [MutableItemProvider]. Old provider does not get updates anymore.
|
||||
* Current state of the scheme used as a default.
|
||||
*/
|
||||
public fun <T : Scheme> T.retarget(provider: MutableItemProvider): T = apply { wrap(provider) }
|
||||
public fun <T : Scheme> T.retarget(provider: MutableItemProvider): T = apply {
|
||||
wrap(provider, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* A shortcut to edit a [Scheme] object in-place
|
||||
@ -135,16 +95,22 @@ public open class SchemeSpec<out T : Scheme>(
|
||||
private val builder: () -> T,
|
||||
) : Specification<T>, Described {
|
||||
|
||||
override fun empty(): T = builder()
|
||||
override fun read(items: ItemProvider): T = empty().also {
|
||||
it.wrap(ObservableMeta().withDefault(items))
|
||||
}
|
||||
|
||||
override fun read(items: ItemProvider): T = wrap(ObservableMeta(), items, descriptor)
|
||||
|
||||
override fun write(target: MutableItemProvider, defaultProvider: ItemProvider): T =
|
||||
wrap(target, defaultProvider, descriptor)
|
||||
override fun write(target: MutableItemProvider): T = empty().also {
|
||||
it.wrap(target)
|
||||
}
|
||||
|
||||
//TODO Generate descriptor from Scheme class
|
||||
override val descriptor: NodeDescriptor? get() = null
|
||||
|
||||
override fun empty(): T = builder().also {
|
||||
it.descriptor = descriptor
|
||||
}
|
||||
|
||||
@Suppress("OVERRIDE_BY_INLINE")
|
||||
final override inline operator fun invoke(action: T.() -> Unit): T = empty().apply(action)
|
||||
|
||||
}
|
@ -35,7 +35,7 @@ public interface Specification<out T : MutableItemProvider> : ReadOnlySpecificat
|
||||
/**
|
||||
* Wrap [MutableItemProvider], using it as inner storage (changes to [Specification] are reflected on [MutableItemProvider]
|
||||
*/
|
||||
public fun write(target: MutableItemProvider, defaultProvider: ItemProvider = ItemProvider.EMPTY): T
|
||||
public fun write(target: MutableItemProvider): T
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,7 +9,7 @@ class SchemeTest {
|
||||
@Test
|
||||
fun testSchemeWrappingBeforeEdit() {
|
||||
val config = MetaBuilder()
|
||||
val scheme = TestScheme.wrap(config)
|
||||
val scheme = TestScheme.write(config)
|
||||
scheme.a = 29
|
||||
assertEquals(29, config["a"].int)
|
||||
}
|
||||
|
@ -9,16 +9,7 @@ internal class TestScheme : Scheme() {
|
||||
var a by int()
|
||||
var b by string()
|
||||
|
||||
companion object : Specification<TestScheme> {
|
||||
override fun empty(): TestScheme = TestScheme()
|
||||
|
||||
override fun read(items: ItemProvider): TestScheme =
|
||||
wrap(MetaBuilder(), items)
|
||||
|
||||
override fun write(target: MutableItemProvider, defaultProvider: ItemProvider): TestScheme =
|
||||
wrap(target, defaultProvider)
|
||||
|
||||
}
|
||||
companion object : SchemeSpec<TestScheme>(::TestScheme)
|
||||
}
|
||||
|
||||
class SpecificationTest {
|
||||
|
Loading…
Reference in New Issue
Block a user