diff --git a/build.gradle.kts b/build.gradle.kts index 0c2a30ab..67b8fec3 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("ru.mipt.npm.project") } -val dataforgeVersion by extra("0.2.0-dev-4") +val dataforgeVersion by extra("0.2.0-dev-6") val bintrayRepo by extra("dataforge") val githubProject by extra("dataforge-core") diff --git a/dataforge-context/api/dataforge-context.api b/dataforge-context/api/dataforge-context.api index 5443d3b3..51349c64 100644 --- a/dataforge-context/api/dataforge-context.api +++ b/dataforge-context/api/dataforge-context.api @@ -229,6 +229,35 @@ public abstract interface annotation class hep/dataforge/descriptors/ValueDef : public abstract fun type ()[Lhep/dataforge/values/ValueType; } +public final class hep/dataforge/properties/ConfigProperty : hep/dataforge/properties/Property { + public fun (Lhep/dataforge/meta/Config;Lhep/dataforge/names/Name;Lhep/dataforge/meta/transformations/MetaConverter;)V + public final fun getConfig ()Lhep/dataforge/meta/Config; + public final fun getConverter ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getName ()Lhep/dataforge/names/Name; + public fun getValue ()Ljava/lang/Object; + public fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V + public fun removeChangeListener (Ljava/lang/Object;)V + public fun setValue (Ljava/lang/Object;)V +} + +public abstract interface class hep/dataforge/properties/Property { + public abstract fun getValue ()Ljava/lang/Object; + public abstract fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V + public abstract fun removeChangeListener (Ljava/lang/Object;)V + public abstract fun setValue (Ljava/lang/Object;)V +} + +public final class hep/dataforge/properties/Property$DefaultImpls { + public static synthetic fun onChange$default (Lhep/dataforge/properties/Property;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public static synthetic fun removeChangeListener$default (Lhep/dataforge/properties/Property;Ljava/lang/Object;ILjava/lang/Object;)V +} + +public final class hep/dataforge/properties/PropertyKt { + public static final fun bind (Lhep/dataforge/properties/Property;Lhep/dataforge/properties/Property;)V + public static final fun mirror (Lhep/dataforge/properties/Property;Lhep/dataforge/properties/Property;Lkotlinx/coroutines/CoroutineScope;)V + public static final fun toFlow (Lhep/dataforge/properties/Property;)Lkotlinx/coroutines/flow/StateFlow; +} + public final class hep/dataforge/provider/DfTypeKt { public static final fun getDfType (Lkotlin/reflect/KClass;)Ljava/lang/String; } diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt new file mode 100644 index 00000000..329662b5 --- /dev/null +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt @@ -0,0 +1,33 @@ +package hep.dataforge.properties + +import hep.dataforge.meta.Config +import hep.dataforge.meta.DFExperimental +import hep.dataforge.meta.get +import hep.dataforge.meta.transformations.MetaConverter +import hep.dataforge.meta.transformations.nullableItemToObject +import hep.dataforge.meta.transformations.nullableObjectToMetaItem +import hep.dataforge.names.Name + +@DFExperimental +public class ConfigProperty( + public val config: Config, + public val name: Name, + public val converter: MetaConverter, +) : Property { + + override var value: T? + get() = converter.nullableItemToObject(config[name]) + set(value) { + config.setItem(name,converter.nullableObjectToMetaItem(value)) + } + + override fun onChange(owner: Any?, callback: (T?) -> Unit) { + config.onChange(owner) { name, oldItem, newItem -> + if (name == this.name && oldItem != newItem) callback(converter.nullableItemToObject(newItem)) + } + } + + override fun removeChangeListener(owner: Any?) { + config.removeListener(owner) + } +} \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/Property.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/Property.kt new file mode 100644 index 00000000..987cfe4c --- /dev/null +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/Property.kt @@ -0,0 +1,48 @@ +package hep.dataforge.properties + +import hep.dataforge.meta.DFExperimental +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow + +@DFExperimental +public interface Property { + public var value: T + + public fun onChange(owner: Any? = null, callback: (T) -> Unit) + public fun removeChangeListener(owner: Any? = null) +} + +@DFExperimental +@OptIn(ExperimentalCoroutinesApi::class) +public fun Property.toFlow(): StateFlow = MutableStateFlow(value).also { stateFlow -> + onChange { + stateFlow.value = it + } +} + +/** + * Reflect all changes in the [source] property onto this property + * + * @return a mirroring job + */ +@DFExperimental +public fun Property.mirror(source: Property, scope: CoroutineScope) { + source.onChange(this) { + this.value = it + } +} + +/** + * Bi-directional connection between properties + */ +@DFExperimental +public fun Property.bind(other: Property) { + onChange(other) { + other.value = it + } + other.onChange { + this.value = it + } +} \ No newline at end of file diff --git a/dataforge-context/src/jsMain/kotlin/hep/dataforge/properties/bindings.kt b/dataforge-context/src/jsMain/kotlin/hep/dataforge/properties/bindings.kt new file mode 100644 index 00000000..05818cae --- /dev/null +++ b/dataforge-context/src/jsMain/kotlin/hep/dataforge/properties/bindings.kt @@ -0,0 +1,32 @@ +package hep.dataforge.properties + +import hep.dataforge.meta.DFExperimental +import org.w3c.dom.HTMLInputElement + +@DFExperimental +fun HTMLInputElement.bindValue(property: Property) { + if (this.onchange != null) error("Input element already bound") + this.onchange = { + property.value = this.value + Unit + } + property.onChange(this) { + if (value != it) { + value = it + } + } +} + +@DFExperimental +fun HTMLInputElement.bindChecked(property: Property) { + if (this.onchange != null) error("Input element already bound") + this.onchange = { + property.value = this.checked + Unit + } + property.onChange(this) { + if (checked != it) { + checked = it + } + } +} \ No newline at end of file diff --git a/dataforge-data/api/dataforge-data.api b/dataforge-data/api/dataforge-data.api index 60392496..06e99242 100644 --- a/dataforge-data/api/dataforge-data.api +++ b/dataforge-data/api/dataforge-data.api @@ -93,7 +93,6 @@ public final class hep/dataforge/data/DataFilter : hep/dataforge/meta/Scheme { public final fun getFrom ()Ljava/lang/String; public final fun getPattern ()Ljava/lang/String; public final fun getTo ()Ljava/lang/String; - public final fun isEmpty ()Z public final fun setFrom (Ljava/lang/String;)V public final fun setPattern (Ljava/lang/String;)V public final fun setTo (Ljava/lang/String;)V diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt index 51e58ac6..8369080e 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt @@ -20,8 +20,6 @@ public class DataFilter : Scheme() { // val prefix by string() // val suffix by string() - public fun isEmpty(): Boolean = config.isEmpty() - public companion object : SchemeSpec(::DataFilter) } diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index 5fed772c..743f482a 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -6,8 +6,8 @@ public abstract class hep/dataforge/meta/AbstractMetaNode : hep/dataforge/meta/M public abstract class hep/dataforge/meta/AbstractMutableMeta : hep/dataforge/meta/AbstractMetaNode, hep/dataforge/meta/MutableMeta { public fun ()V + protected final fun getChildren ()Ljava/util/Map; public fun getItems ()Ljava/util/Map; - protected final fun get_items ()Ljava/util/Map; protected fun replaceItem (Lhep/dataforge/names/NameToken;Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/MetaItem;)V public fun setItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V protected final fun wrapItem (Lhep/dataforge/meta/MetaItem;)Lhep/dataforge/meta/MetaItem; @@ -38,21 +38,15 @@ public final class hep/dataforge/meta/ConfigKt { public static final fun get (Lhep/dataforge/meta/Config;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/MetaItem; } -public abstract interface class hep/dataforge/meta/Configurable : hep/dataforge/meta/MutableItemProvider, hep/dataforge/meta/descriptors/Described { +public abstract interface class hep/dataforge/meta/Configurable : hep/dataforge/meta/MutableItemProvider { public abstract fun getConfig ()Lhep/dataforge/meta/Config; - public abstract fun getDefaultItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; - public abstract fun getDescriptor ()Lhep/dataforge/meta/descriptors/NodeDescriptor; public abstract fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; public abstract fun setItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V - public abstract fun validateItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z } public final class hep/dataforge/meta/Configurable$DefaultImpls { - public static fun getDefaultItem (Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; - public static fun getDescriptor (Lhep/dataforge/meta/Configurable;)Lhep/dataforge/meta/descriptors/NodeDescriptor; public static fun getItem (Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; public static fun setItem (Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V - public static fun validateItem (Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z } public final class hep/dataforge/meta/ConfigurableKt { @@ -60,18 +54,6 @@ public final class hep/dataforge/meta/ConfigurableKt { public static synthetic fun config$default (Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; public static final fun configure (Lhep/dataforge/meta/Configurable;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Configurable; public static final fun configure (Lhep/dataforge/meta/Configurable;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; - public static final fun getItem (Lhep/dataforge/meta/Configurable;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem; - public static final fun node (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; - public static synthetic fun node$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; - public static final fun setItem (Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V - public static final fun setItem (Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;Lhep/dataforge/values/Value;)V - public static final fun setItem (Lhep/dataforge/meta/Configurable;Ljava/lang/String;Lhep/dataforge/meta/Meta;)V - public static final fun setItem (Lhep/dataforge/meta/Configurable;Ljava/lang/String;Lhep/dataforge/meta/MetaItem;)V - public static final fun setItem (Lhep/dataforge/meta/Configurable;Ljava/lang/String;Lhep/dataforge/values/Value;)V - public static final fun spec (Lhep/dataforge/meta/Configurable;Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; - public static final fun spec (Lhep/dataforge/meta/Configurable;Lhep/dataforge/meta/Specification;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; - public static synthetic fun spec$default (Lhep/dataforge/meta/Configurable;Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; - public static synthetic fun spec$default (Lhep/dataforge/meta/Configurable;Lhep/dataforge/meta/Specification;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; } public abstract interface annotation class hep/dataforge/meta/DFBuilder : java/lang/annotation/Annotation { @@ -196,9 +178,12 @@ public abstract interface class hep/dataforge/meta/Meta : hep/dataforge/meta/Ite public static final field Companion Lhep/dataforge/meta/Meta$Companion; public static final field TYPE Ljava/lang/String; public static final field VALUE_KEY Ljava/lang/String; + public abstract fun equals (Ljava/lang/Object;)Z public abstract fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; public abstract fun getItems ()Ljava/util/Map; + public abstract fun hashCode ()I public abstract fun toMeta ()Lhep/dataforge/meta/Meta; + public abstract fun toString ()Ljava/lang/String; } public final class hep/dataforge/meta/Meta$Companion { @@ -358,14 +343,6 @@ public abstract interface class hep/dataforge/meta/MetaRepr { public abstract fun toMeta ()Lhep/dataforge/meta/Meta; } -public class hep/dataforge/meta/MetaScheme : hep/dataforge/meta/Scheme { - public fun (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;Lhep/dataforge/meta/Config;)V - public synthetic fun (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;Lhep/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun getDefaultLayer ()Lhep/dataforge/meta/Meta; - public synthetic fun getDescriptor ()Lhep/dataforge/meta/descriptors/ItemDescriptor; - public fun getDescriptor ()Lhep/dataforge/meta/descriptors/NodeDescriptor; -} - public final class hep/dataforge/meta/MetaSerializer : kotlinx/serialization/KSerializer { public static final field INSTANCE Lhep/dataforge/meta/MetaSerializer; public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/meta/Meta; @@ -375,6 +352,18 @@ public final class hep/dataforge/meta/MetaSerializer : kotlinx/serialization/KSe public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V } +public final class hep/dataforge/meta/MetaWithDefault : hep/dataforge/meta/MetaBase { + public fun (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)V + public final fun getDefault ()Lhep/dataforge/meta/ItemProvider; + public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public fun getItems ()Ljava/util/Map; + public final fun getMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/meta/MetaWithDefaultKt { + public static final fun withDefault (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MetaWithDefault; +} + public final class hep/dataforge/meta/MutableItemDelegateKt { public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty; @@ -437,6 +426,29 @@ public abstract interface class hep/dataforge/meta/MutableItemProvider : hep/dat public abstract fun setItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V } +public final class hep/dataforge/meta/MutableItemProviderKt { + public static final fun getItem (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem; + public static final fun node (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun node$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun remove (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)V + public static final fun remove (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Iterable;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Object;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/NameToken;Ljava/lang/Object;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Ljava/lang/Iterable;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Ljava/lang/Object;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V + public static final fun setIndexed (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun setIndexed$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + public static final fun setIndexedItems (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun setIndexedItems$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + public static final fun setItem (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Lhep/dataforge/meta/MetaItem;)V + public static final fun setNode (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V + public static final fun setNode (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Lhep/dataforge/meta/Meta;)V + public static final fun setValue (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lhep/dataforge/values/Value;)V + public static final fun setValue (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Lhep/dataforge/values/Value;)V +} + public abstract interface class hep/dataforge/meta/MutableMeta : hep/dataforge/meta/MetaNode, hep/dataforge/meta/MutableItemProvider { public abstract fun getItems ()Ljava/util/Map; } @@ -450,24 +462,6 @@ public final class hep/dataforge/meta/MutableMetaKt { public static final fun append (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Ljava/lang/Object;)V public static final fun append (Lhep/dataforge/meta/MutableMeta;Ljava/lang/String;Ljava/lang/Object;)V public static final fun edit (Lhep/dataforge/meta/AbstractMutableMeta;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V - public static final fun remove (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;)V - public static final fun remove (Lhep/dataforge/meta/MutableMeta;Ljava/lang/String;)V - public static final fun set (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V - public static final fun set (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Ljava/lang/Iterable;)V - public static final fun set (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Ljava/lang/Object;)V - public static final fun set (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/NameToken;Ljava/lang/Object;)V - public static final fun set (Lhep/dataforge/meta/MutableMeta;Ljava/lang/String;Ljava/lang/Iterable;)V - public static final fun set (Lhep/dataforge/meta/MutableMeta;Ljava/lang/String;Ljava/lang/Object;)V - public static final fun set (Lhep/dataforge/meta/MutableMeta;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V - public static final fun setIndexed (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)V - public static synthetic fun setIndexed$default (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V - public static final fun setIndexedItems (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)V - public static synthetic fun setIndexedItems$default (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V - public static final fun setItem (Lhep/dataforge/meta/MutableMeta;Ljava/lang/String;Lhep/dataforge/meta/MetaItem;)V - public static final fun setNode (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V - public static final fun setNode (Lhep/dataforge/meta/MutableMeta;Ljava/lang/String;Lhep/dataforge/meta/Meta;)V - public static final fun setValue (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Lhep/dataforge/values/Value;)V - public static final fun setValue (Lhep/dataforge/meta/MutableMeta;Ljava/lang/String;Lhep/dataforge/values/Value;)V public static final fun update (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/meta/Meta;)V } @@ -483,22 +477,23 @@ public final class hep/dataforge/meta/ObservableMeta$DefaultImpls { public class hep/dataforge/meta/Scheme : hep/dataforge/meta/Configurable, hep/dataforge/meta/MetaRepr, hep/dataforge/meta/descriptors/Described { public fun ()V - public fun (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)V + public fun (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public synthetic fun (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun getConfig ()Lhep/dataforge/meta/Config; - public fun getDefaultItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public final fun getDefaultItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; public fun getDefaultLayer ()Lhep/dataforge/meta/Meta; - public final fun getDefaultProvider ()Lhep/dataforge/meta/ItemProvider; public synthetic fun getDescriptor ()Lhep/dataforge/meta/descriptors/ItemDescriptor; public fun getDescriptor ()Lhep/dataforge/meta/descriptors/NodeDescriptor; public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public final fun isEmpty ()Z public fun setItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V public fun toMeta ()Lhep/dataforge/meta/Laminate; public synthetic fun toMeta ()Lhep/dataforge/meta/Meta; - public fun validateItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z + public final fun validateItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z } public final class hep/dataforge/meta/SchemeKt { - public static final fun asScheme (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MetaScheme; + public static final fun asScheme (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Scheme; public static final fun invoke (Lhep/dataforge/meta/Scheme;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Scheme; public static final fun toScheme (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; public static synthetic fun toScheme$default (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/meta/Configurable; @@ -507,12 +502,8 @@ public final class hep/dataforge/meta/SchemeKt { public class hep/dataforge/meta/SchemeSpec : hep/dataforge/meta/Specification { public fun (Lkotlin/jvm/functions/Function0;)V public fun (Lkotlin/jvm/functions/Function2;)V - public synthetic fun empty ()Lhep/dataforge/meta/Configurable; - public fun empty ()Lhep/dataforge/meta/Scheme; - public synthetic fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; - public final fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Scheme; - public synthetic fun wrap (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Configurable; - public fun wrap (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme; + public synthetic fun wrap (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; + public fun wrap (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme; } public final class hep/dataforge/meta/SealedMeta : hep/dataforge/meta/AbstractMetaNode { @@ -520,25 +511,27 @@ public final class hep/dataforge/meta/SealedMeta : hep/dataforge/meta/AbstractMe } public abstract interface class hep/dataforge/meta/Specification { - public abstract fun empty ()Lhep/dataforge/meta/Configurable; - public abstract fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; - public abstract fun wrap (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Configurable; + public abstract fun wrap (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; } public final class hep/dataforge/meta/Specification$DefaultImpls { - public static fun empty (Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/Configurable; - public static fun invoke (Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; - public static synthetic fun wrap$default (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lhep/dataforge/meta/Configurable; + public static synthetic fun wrap$default (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lhep/dataforge/meta/MutableItemProvider; } public final class hep/dataforge/meta/SpecificationKt { - public static final fun configSpec (Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/Configurable; - public static final fun configure (Lhep/dataforge/meta/Configurable;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; + public static final fun configSpec (Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider; + public static final fun configure (Lhep/dataforge/meta/MetaRepr;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MetaRepr; public static final fun createStyle (Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Meta; - public static final fun spec (Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/Configurable; + public static final fun empty (Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider; + public static final fun invoke (Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; + public static final fun spec (Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider; + public static final fun spec (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Scheme;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun spec (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun spec$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Scheme;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun spec$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; public static final fun update (Lhep/dataforge/meta/Configurable;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; - public static final fun update (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Config;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; - public static final fun wrap (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Configurable; + public static final fun update (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; + public static final fun wrap (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MutableItemProvider; } public abstract interface class hep/dataforge/meta/descriptors/Described { @@ -775,7 +768,6 @@ public final class hep/dataforge/names/NameKt { public static final fun get (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; public static synthetic fun get$default (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/Object; public static final fun getLength (Lhep/dataforge/names/Name;)I - public static final fun hasIndex (Lhep/dataforge/names/NameToken;)Z public static final fun isEmpty (Lhep/dataforge/names/Name;)Z public static final fun lastOrNull (Lhep/dataforge/names/Name;)Lhep/dataforge/names/NameToken; public static final fun plus (Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;)Lhep/dataforge/names/Name; @@ -787,7 +779,6 @@ public final class hep/dataforge/names/NameKt { public static final fun startsWith (Lhep/dataforge/names/Name;Lhep/dataforge/names/NameToken;)Z public static final fun toName (Ljava/lang/String;)Lhep/dataforge/names/Name; public static final fun withIndex (Lhep/dataforge/names/Name;Ljava/lang/String;)Lhep/dataforge/names/Name; - public static final fun withIndex (Lhep/dataforge/names/NameToken;Ljava/lang/String;)Lhep/dataforge/names/NameToken; } public final class hep/dataforge/names/NameToken { @@ -814,6 +805,11 @@ public final class hep/dataforge/names/NameToken$Companion : kotlinx/serializati public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class hep/dataforge/names/NameTokenKt { + public static final fun hasIndex (Lhep/dataforge/names/NameToken;)Z + public static final fun withIndex (Lhep/dataforge/names/NameToken;Ljava/lang/String;)Lhep/dataforge/names/NameToken; +} + public final class hep/dataforge/values/DoubleArrayValue : hep/dataforge/values/Value { public fun ([D)V public fun equals (Ljava/lang/Object;)Z diff --git a/dataforge-meta/build.gradle.kts b/dataforge-meta/build.gradle.kts index 2d4aac0c..980924a7 100644 --- a/dataforge-meta/build.gradle.kts +++ b/dataforge-meta/build.gradle.kts @@ -1,16 +1,12 @@ -import ru.mipt.npm.gradle.KScienceVersions - plugins { id("ru.mipt.npm.mpp") id("ru.mipt.npm.native") } kscience { - useSerialization() + useSerialization{ + json() + } } -description = "Meta definition and basic operations on meta" - -dependencies{ - commonMainApi("org.jetbrains.kotlinx:kotlinx-serialization-json:${KScienceVersions.serializationVersion}") -} \ No newline at end of file +description = "Meta definition and basic operations on meta" \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt index d1691e4e..2674d0a8 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt @@ -4,10 +4,8 @@ import hep.dataforge.names.Name import hep.dataforge.names.NameToken import hep.dataforge.names.asName import hep.dataforge.names.plus -import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable -import kotlinx.serialization.Serializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder @@ -53,12 +51,12 @@ public class Config() : AbstractMutableMeta(), ObservableMeta { override fun replaceItem(key: NameToken, oldItem: MetaItem?, newItem: MetaItem?) { if (newItem == null) { - _items.remove(key) + children.remove(key) if (oldItem != null && oldItem is MetaItem.NodeItem) { oldItem.node.removeListener(this) } } else { - _items[key] = newItem + children[key] = newItem if (newItem is MetaItem.NodeItem) { newItem.node.onChange(this) { name, oldChild, newChild -> itemChanged(key + name, oldChild, newChild) @@ -75,8 +73,6 @@ public class Config() : AbstractMutableMeta(), ObservableMeta { override fun empty(): Config = Config() - @OptIn(ExperimentalSerializationApi::class) - @Serializer(Config::class) public companion object ConfigSerializer : KSerializer { public fun empty(): Config = Config() diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt index 9fd6cdb3..2308bef2 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt @@ -1,67 +1,30 @@ package hep.dataforge.meta -import hep.dataforge.meta.descriptors.* import hep.dataforge.names.Name -import hep.dataforge.names.asName -import hep.dataforge.names.toName -import hep.dataforge.values.Value import kotlin.properties.ReadWriteProperty -import kotlin.reflect.KProperty /** - * A container that holds a [Config] and a default item provider. - * Default item provider could be use for example to reference parent configuration. - * It is not possible to know if some property is declared by provider just by looking on [Configurable], - * this information should be provided externally. + * A container that holds a [Config]. */ -public interface Configurable : Described, MutableItemProvider { +public interface Configurable : MutableItemProvider { /** * Backing config */ public val config: Config - /** - * Default meta item provider - */ - public fun getDefaultItem(name: Name): MetaItem<*>? = null - - /** - * Check if property with given [name] could be assigned to [item] - */ - public fun validateItem(name: Name, item: MetaItem<*>?): Boolean { - val descriptor = descriptor?.get(name) - return descriptor?.validateItem(item) ?: true - } - - override val descriptor: NodeDescriptor? get() = null - /** * Get a property with default */ - override fun getItem(name: Name): MetaItem<*>? = - config[name] ?: getDefaultItem(name) ?: descriptor?.get(name)?.defaultItem() + override fun getItem(name: Name): MetaItem<*>? = config[name] /** * Set a configurable property */ override fun setItem(name: Name, item: MetaItem<*>?) { - if (validateItem(name, item)) { - config.setItem(name, item) - } else { - error("Validation failed for property $name with value $item") - } + config.setItem(name, item) } } -public fun Configurable.getItem(key: String): MetaItem<*>? = getItem(key.toName()) - -public fun Configurable.setItem(name: Name, value: Value?): Unit = setItem(name, value?.let { MetaItem.ValueItem(value) }) -public fun Configurable.setItem(name: Name, meta: Meta?): Unit = setItem(name, meta?.let { MetaItem.NodeItem(meta) }) - -public fun Configurable.setItem(key: String, item: MetaItem<*>?): Unit = setItem(key.toName(), item) - -public fun Configurable.setItem(key: String, value: Value?): Unit = setItem(key, value?.let { MetaItem.ValueItem(value) }) -public fun Configurable.setItem(key: String, meta: Meta?): Unit = setItem(key, meta?.let { MetaItem.NodeItem(meta) }) public fun T.configure(meta: Meta): T = this.apply { config.update(meta) } @@ -70,39 +33,4 @@ public inline fun T.configure(action: Config.() -> Unit): T = /* Node delegates */ -public fun Configurable.config(key: Name? = null): ReadWriteProperty = - config.node(key) - -public fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty = item(key).convert( - reader = { it.node }, - writer = { it?.let { MetaItem.NodeItem(it) } } -) - -public fun Configurable.spec( - spec: Specification, key: Name? = null -): ReadWriteProperty = object : ReadWriteProperty { - override fun getValue(thisRef: Any?, property: KProperty<*>): T? { - val name = key ?: property.name.asName() - return config[name].node?.let { spec.wrap(it) } - } - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { - val name = key ?: property.name.asName() - config[name] = value?.config - } -} - -public fun Configurable.spec( - spec: Specification, default: T, key: Name? = null -): ReadWriteProperty = object : ReadWriteProperty { - override fun getValue(thisRef: Any?, property: KProperty<*>): T { - val name = key ?: property.name.asName() - return config[name].node?.let { spec.wrap(it) } ?: default - } - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { - val name = key ?: property.name.asName() - config[name] = value.config - } -} - +public fun Configurable.config(key: Name? = null): ReadWriteProperty = config.node(key) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt index 5c992c6b..c8ed6755 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt @@ -66,6 +66,7 @@ public fun M.asMetaItem(): NodeItem = NodeItem(this) * The object that could be represented as [Meta]. Meta provided by [toMeta] method should fully represent object state. * Meaning that two states with the same meta are equal. */ +@Serializable(MetaSerializer::class) public interface MetaRepr { public fun toMeta(): Meta } @@ -104,12 +105,11 @@ public interface Meta : MetaRepr, ItemProvider { override fun toMeta(): Meta = seal() - //TODO to be restored on 1.4.30 after https://youtrack.jetbrains.com/issue/KT-41765 si fixed -// override fun equals(other: Any?): Boolean -// -// override fun hashCode(): Int -// -// override fun toString(): String + override fun equals(other: Any?): Boolean + + override fun hashCode(): Int + + override fun toString(): String public companion object { public const val TYPE: String = "meta" diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt index b6e933f6..cd041275 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt @@ -68,7 +68,7 @@ public class MetaBuilder : AbstractMutableMeta() { @JvmName("putMetas") public infix fun String.put(value: Iterable) { - this@MetaBuilder[this] = value.toList() + set(this,value.toList()) } public infix fun String.put(metaBuilder: MetaBuilder.() -> Unit) { @@ -110,7 +110,7 @@ public class MetaBuilder : AbstractMutableMeta() { @JvmName("putMetas") public infix fun Name.put(value: Iterable) { - this@MetaBuilder[this] = value.toList() + set(this, value.toList()) } public infix fun Name.put(metaBuilder: MetaBuilder.() -> Unit) { diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaSerializer.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaSerializer.kt index 7184ae3a..b20adba8 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaSerializer.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaSerializer.kt @@ -5,7 +5,6 @@ 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.* import kotlinx.serialization.encoding.* @@ -52,8 +51,6 @@ public object MetaItemSerializer : KSerializer> { /** * Serialized for meta */ -@OptIn(ExperimentalSerializationApi::class) -@Serializer(Meta::class) public object MetaSerializer : KSerializer { private val mapSerializer: KSerializer>> = MapSerializer( diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaWithDefault.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaWithDefault.kt new file mode 100644 index 00000000..2a225121 --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaWithDefault.kt @@ -0,0 +1,18 @@ +package hep.dataforge.meta + +import hep.dataforge.names.Name +import hep.dataforge.names.NameToken + +/** + * Meta object with default provider for items not present in the initial meta. + */ +public class MetaWithDefault(public val meta: Meta, public val default: ItemProvider) : MetaBase() { + override val items: Map> + get() = meta.items + + override fun getItem(name: Name): MetaItem<*>? { + return meta[name] ?: default.getItem(name) + } +} + +public fun Meta.withDefault(default: ItemProvider): MetaWithDefault = MetaWithDefault(this, default) \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemProvider.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemProvider.kt new file mode 100644 index 00000000..6a43af6e --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemProvider.kt @@ -0,0 +1,88 @@ +package hep.dataforge.meta + +import hep.dataforge.names.* +import hep.dataforge.values.Value +import kotlin.properties.ReadWriteProperty + +public interface MutableItemProvider : ItemProvider { + public fun setItem(name: Name, item: MetaItem<*>?) +} + +public fun MutableItemProvider.getItem(key: String): MetaItem<*>? = getItem(key.toName()) + +public fun MutableItemProvider.setValue(name: Name, value: Value?): Unit = + setItem(name, value?.let { MetaItem.ValueItem(value) }) + +public fun MutableItemProvider.setNode(name: Name, meta: Meta?): Unit = + setItem(name, meta?.let { MetaItem.NodeItem(meta) }) + +public fun MutableItemProvider.setItem(key: String, item: MetaItem<*>?): Unit = setItem(key.toName(), item) + +public fun MutableItemProvider.setValue(key: String, value: Value?): Unit = + setItem(key, value?.let { MetaItem.ValueItem(value) }) + +public fun MutableItemProvider.setNode(key: String, meta: Meta?): Unit = + setItem(key, meta?.let { MetaItem.NodeItem(meta) }) + +public fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty = item(key).convert( + reader = { it.node }, + writer = { it?.let { MetaItem.NodeItem(it) } } +) + +@Suppress("NOTHING_TO_INLINE") +public inline fun MutableItemProvider.remove(name: Name): Unit = setItem(name, null) + +@Suppress("NOTHING_TO_INLINE") +public inline fun MutableItemProvider.remove(name: String): Unit = remove(name.toName()) + + +/** + * Universal unsafe set method + */ +public operator fun MutableItemProvider.set(name: Name, value: Any?) { + when (value) { + null -> remove(name) + is MetaItem<*> -> setItem(name, value) + is Meta -> setNode(name, value) + is Configurable -> setNode(name, value.config) + else -> setValue(name, Value.of(value)) + } +} + +public operator fun MutableItemProvider.set(name: NameToken, value: Any?): Unit = + set(name.asName(), value) + +public operator fun MutableItemProvider.set(key: String, value: Any?): Unit = + set(key.toName(), value) + +public operator fun MutableItemProvider.set(key: String, index: String, value: Any?): Unit = + set(key.toName().withIndex(index), value) + + + +/* Same name siblings generation */ + +public fun MutableItemProvider.setIndexedItems( + name: Name, + items: Iterable>, + indexFactory: (MetaItem<*>, index: Int) -> String = { _, index -> index.toString() } +) { + val tokens = name.tokens.toMutableList() + val last = tokens.last() + items.forEachIndexed { index, meta -> + val indexedToken = NameToken(last.body, last.index + indexFactory(meta, index)) + tokens[tokens.lastIndex] = indexedToken + setItem(Name(tokens), meta) + } +} + +public fun MutableItemProvider.setIndexed( + name: Name, + metas: Iterable, + indexFactory: (Meta, index: Int) -> String = { _, index -> index.toString() } +) { + setIndexedItems(name, metas.map { MetaItem.NodeItem(it) }) { item, index -> indexFactory(item.node!!, index) } +} + +public operator fun MutableItemProvider.set(name: Name, metas: Iterable): Unit = setIndexed(name, metas) +public operator fun MutableItemProvider.set(name: String, metas: Iterable): Unit = setIndexed(name.toName(), metas) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt index 25cf003f..7903ba87 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt @@ -1,11 +1,6 @@ package hep.dataforge.meta import hep.dataforge.names.* -import hep.dataforge.values.Value - -public interface MutableItemProvider : ItemProvider { - public fun setItem(name: Name, item: MetaItem<*>?) -} public interface MutableMeta> : MetaNode, MutableItemProvider { override val items: Map> @@ -19,18 +14,18 @@ public interface MutableMeta> : MetaNode, MutableItemP * Changes in Meta are not thread safe. */ public abstract class AbstractMutableMeta> : AbstractMetaNode(), MutableMeta { - protected val _items: MutableMap> = LinkedHashMap() + protected val children: MutableMap> = LinkedHashMap() override val items: Map> - get() = _items + get() = children //protected abstract fun itemChanged(name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) protected open fun replaceItem(key: NameToken, oldItem: MetaItem?, newItem: MetaItem?) { if (newItem == null) { - _items.remove(key) + children.remove(key) } else { - _items[key] = newItem + children[key] = newItem } //itemChanged(key.asName(), oldItem, newItem) } @@ -72,48 +67,6 @@ public abstract class AbstractMutableMeta> : AbstractMetaNode } } - -@Suppress("NOTHING_TO_INLINE") -public inline fun MutableMeta<*>.remove(name: Name): Unit = setItem(name, null) - -@Suppress("NOTHING_TO_INLINE") -public inline fun MutableMeta<*>.remove(name: String): Unit = remove(name.toName()) - -public operator fun MutableMeta<*>.set(name: Name, item: MetaItem<*>?): Unit = setItem(name, item) - -public fun MutableMeta<*>.setValue(name: Name, value: Value): Unit = setItem(name, MetaItem.ValueItem(value)) - -public fun MutableMeta<*>.setValue(name: String, value: Value): Unit = set(name.toName(), value) - -public fun MutableMeta<*>.setItem(name: String, item: MetaItem<*>?): Unit = setItem(name.toName(), item) - -public fun MutableMeta<*>.setNode(name: Name, node: Meta): Unit = - setItem(name, MetaItem.NodeItem(node)) - -public fun MutableMeta<*>.setNode(name: String, node: Meta): Unit = setNode(name.toName(), node) - -/** - * Universal unsafe set method - */ -public operator fun MutableMeta<*>.set(name: Name, value: Any?) { - when (value) { - null -> remove(name) - is MetaItem<*> -> setItem(name, value) - is Meta -> setNode(name, value) - is Configurable -> setNode(name, value.config) - else -> setValue(name, Value.of(value)) - } -} - -public operator fun MutableMeta<*>.set(name: NameToken, value: Any?): Unit = - set(name.asName(), value) - -public operator fun MutableMeta<*>.set(key: String, value: Any?): Unit = - set(key.toName(), value) - -public operator fun MutableMeta<*>.set(key: String, index: String, value: Any?): Unit = - set(key.toName().withIndex(index), value) - /** * Update existing mutable node with another node. The rules are following: * * value replaces anything @@ -130,33 +83,6 @@ public fun > M.update(meta: Meta) { } } -/* Same name siblings generation */ - -public fun MutableMeta<*>.setIndexedItems( - name: Name, - items: Iterable>, - indexFactory: (MetaItem<*>, index: Int) -> String = { _, index -> index.toString() } -) { - val tokens = name.tokens.toMutableList() - val last = tokens.last() - items.forEachIndexed { index, meta -> - val indexedToken = NameToken(last.body, last.index + indexFactory(meta, index)) - tokens[tokens.lastIndex] = indexedToken - setItem(Name(tokens), meta) - } -} - -public fun MutableMeta<*>.setIndexed( - name: Name, - metas: Iterable, - indexFactory: (Meta, index: Int) -> String = { _, index -> index.toString() } -) { - setIndexedItems(name, metas.map { MetaItem.NodeItem(it) }) { item, index -> indexFactory(item.node!!, index) } -} - -public operator fun MutableMeta<*>.set(name: Name, metas: Iterable): Unit = setIndexed(name, metas) -public operator fun MutableMeta<*>.set(name: String, metas: Iterable): Unit = setIndexed(name.toName(), metas) - /** * Append the node with a same-name-sibling, automatically generating numerical index */ diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt index 913f5a3d..a85e464f 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt @@ -1,31 +1,49 @@ package hep.dataforge.meta -import hep.dataforge.meta.descriptors.Described -import hep.dataforge.meta.descriptors.NodeDescriptor -import hep.dataforge.meta.descriptors.defaultItem -import hep.dataforge.meta.descriptors.get +import hep.dataforge.meta.descriptors.* import hep.dataforge.names.Name import hep.dataforge.names.NameToken import hep.dataforge.names.asName /** * A base for delegate-based or descriptor-based scheme. [Scheme] has an empty constructor to simplify usage from [Specification]. + * Default item provider and [NodeDescriptor] are optional */ public open class Scheme( - config: Config, - defaultProvider: ItemProvider, + config: Config = Config(), + internal var default: ItemProvider? = null, + override val descriptor: NodeDescriptor? = null, ) : Configurable, Described, MetaRepr { override var config: Config = config internal set - public var defaultProvider: ItemProvider = defaultProvider - internal set + public fun getDefaultItem(name: Name): MetaItem<*>? { + return default?.getItem(name) ?: descriptor?.get(name)?.defaultItem() + } - public constructor() : this(Config(), ItemProvider { null }) + /** + * Get a property with default + */ + override fun getItem(name: Name): MetaItem<*>? = config[name] ?: getDefaultItem(name) - override fun getDefaultItem(name: Name): MetaItem<*>? { - return defaultProvider.getItem(name) ?: descriptor?.get(name)?.defaultItem() + /** + * Check if property with given [name] could be assigned to [item] + */ + public fun validateItem(name: Name, item: MetaItem<*>?): Boolean { + val descriptor = descriptor?.get(name) + return descriptor?.validateItem(item) ?: true + } + + /** + * Set a configurable property + */ + override fun setItem(name: Name, item: MetaItem<*>?) { + if (validateItem(name, item)) { + super.setItem(name, item) + } else { + error("Validation failed for property $name with value $item") + } } /** @@ -33,22 +51,23 @@ public open class Scheme( * values if default value is unavailable. * Values from [defaultProvider] completely replace */ - public open val defaultLayer: Meta get() = DefaultLayer() - - override fun toMeta(): Laminate = Laminate(config, defaultLayer) - - private inner class DefaultLayer : MetaBase() { - override val items: Map> = buildMap { - descriptor?.items?.forEach { (key, itemDescriptor) -> - val token = NameToken(key) - val name = token.asName() - val item = defaultProvider.getItem(name) ?: itemDescriptor.defaultItem() - if (item != null) { - put(token, item) + public open val defaultLayer: Meta + get() = object : MetaBase() { + override val items: Map> = buildMap { + descriptor?.items?.forEach { (key, itemDescriptor) -> + val token = NameToken(key) + val name = token.asName() + val item = default?.getItem(name) ?: itemDescriptor.defaultItem() + if (item != null) { + put(token, item) + } } } } - } + + override fun toMeta(): Laminate = Laminate(config, defaultLayer) + + public fun isEmpty(): Boolean = config.isEmpty() } /** @@ -66,30 +85,32 @@ public open class SchemeSpec( public constructor(emptyBuilder: () -> T) : this({ config: Config, defaultProvider: ItemProvider -> emptyBuilder().apply { this.config = config - this.defaultProvider = defaultProvider + this.default = defaultProvider } }) - override fun empty(): T = builder(Config(), ItemProvider.EMPTY) - - override fun wrap(config: Config, defaultProvider: ItemProvider): T = builder(config, defaultProvider) - - @Suppress("OVERRIDE_BY_INLINE") - final override inline operator fun invoke(action: T.() -> Unit): T = empty().apply(action) + /** + * If the provided [Meta] is a [Config] use it as a scheme base, otherwise use it as default. + */ + override fun wrap(meta: Meta, defaultProvider: ItemProvider): T = if (meta is Config) { + builder(meta, defaultProvider) + } else { + builder(Config(), meta.withDefault(defaultProvider)) + } } -/** - * A scheme that uses [Meta] as a default layer - */ -public open class MetaScheme( - private val meta: Meta, - override val descriptor: NodeDescriptor? = null, - config: Config = Config(), -) : Scheme(config, meta) { - override val defaultLayer: Meta get() = Laminate(meta, descriptor?.defaultItem().node) -} +///** +// * A scheme that uses [Meta] as a default layer +// */ +//public open class MetaScheme( +// private val meta: Meta, +// override val descriptor: NodeDescriptor? = null, +// config: Config = Config(), +//) : Scheme(config, meta) { +// override val defaultLayer: Meta get() = Laminate(meta, descriptor?.defaultItem().node) +//} -public fun Meta.asScheme(): MetaScheme = MetaScheme(this) +public fun Meta.asScheme(): Scheme = Scheme(this.asConfig(), null, null) public fun Meta.toScheme(spec: Specification, block: T.() -> Unit = {}): T = spec.wrap(this).apply(block) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt index 7988f0c1..03bc36b6 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt @@ -1,32 +1,36 @@ package hep.dataforge.meta +import hep.dataforge.names.Name +import hep.dataforge.names.asName import kotlin.jvm.JvmName +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty /** * Allows to apply custom configuration in a type safe way to simple untyped configuration. * By convention [Scheme] companion should inherit this class * */ -public interface Specification { - public fun empty(): T = wrap() - +public interface Specification { /** * Wrap generic configuration producing instance of desired type */ - public fun wrap(config: Config = Config(), defaultProvider: ItemProvider = ItemProvider{ null }): T - - public operator fun invoke(action: T.() -> Unit): T = empty().apply(action) + public fun wrap(meta: Meta, defaultProvider: ItemProvider = ItemProvider.EMPTY): T } +public operator fun Specification.invoke(action: T.() -> Unit): T = empty().apply(action) + +public fun Specification.empty(): T = wrap(Config()) + /** * Update given configuration using given type as a builder */ -public fun Specification.update(config: Config, action: T.() -> Unit): T = wrap(config).apply(action) +public fun Specification.update(meta: Meta, action: T.() -> Unit): T = wrap(meta).apply(action) /** - * Wrap a configuration using static meta as default + * Create a read-only version of */ -public fun Specification.wrap(source: Meta): T { +public fun Specification.wrap(source: Meta): T { val default = source.seal() return wrap(source.asConfig(), default) } @@ -34,26 +38,56 @@ public fun Specification.wrap(source: Meta): T { /** * Apply specified configuration to configurable */ -public fun > T.configure(spec: S, action: C.() -> Unit): T = - apply { spec.update(config, action) } +public fun > T.configure(spec: S, action: C.() -> Unit): T = + apply { spec.update(toMeta(), action) } /** * Update configuration using given specification */ -public fun > Configurable.update(spec: S, action: C.() -> Unit): Configurable = +public fun > Configurable.update(spec: S, action: C.() -> Unit): Configurable = apply { spec.update(config, action) } /** * Create a style based on given specification */ -public fun > S.createStyle(action: C.() -> Unit): Meta = +public fun > S.createStyle(action: C.() -> Unit): Meta = Config().also { update(it, action) } -public fun MetaItem<*>.spec(spec: Specification): T? = node?.let { +public fun MetaItem<*>.spec(spec: Specification): T? = node?.let { spec.wrap( Config(), it ) } @JvmName("configSpec") -public fun MetaItem.spec(spec: Specification): T? = node?.let { spec.wrap(it) } +public fun MetaItem.spec(spec: Specification): T? = node?.let { spec.wrap(it) } + +public fun MutableItemProvider.spec( + spec: Specification, key: Name? = null +): ReadWriteProperty = object : ReadWriteProperty { + override fun getValue(thisRef: Any?, property: KProperty<*>): T? { + val name = key ?: property.name.asName() + return getItem(name).node?.let { spec.wrap(it) } + } + + override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { + val name = key ?: property.name.asName() + setItem(name, value?.toMeta()?.asMetaItem()) + } +} + +public fun MutableItemProvider.spec( + spec: Specification, + default: T, + key: Name? = null +): ReadWriteProperty = object : ReadWriteProperty { + override fun getValue(thisRef: Any?, property: KProperty<*>): T { + val name = key ?: property.name.asName() + return getItem(name).node?.let { spec.wrap(it) } ?: default + } + + override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { + val name = key ?: property.name.asName() + setItem(name, value.toMeta().asMetaItem()) + } +} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt index 0791e080..9cce4314 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt @@ -1,9 +1,7 @@ package hep.dataforge.names -import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable -import kotlinx.serialization.Serializer import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor @@ -16,7 +14,7 @@ import kotlinx.serialization.encoding.Encoder * The name is a dot separated list of strings like `token1.token2.token3`. * Each token could contain additional index in square brackets. */ -@Serializable +@Serializable(Name.Companion::class) public class Name(public val tokens: List) { //TODO to be transformed into inline class after they are supported with serialization @@ -38,8 +36,6 @@ public class Name(public val tokens: List) { } } - @OptIn(ExperimentalSerializationApi::class) - @Serializer(Name::class) public companion object : KSerializer { public const val NAME_SEPARATOR: String = "." @@ -82,55 +78,6 @@ public fun Name.lastOrNull(): NameToken? = tokens.lastOrNull() */ public fun Name.firstOrNull(): NameToken? = tokens.firstOrNull() -/** - * A single name token. Body is not allowed to be empty. - * Following symbols are prohibited in name tokens: `{}.:\`. - * A name token could have appendix in square brackets called *index* - */ -@Serializable -public data class NameToken(val body: String, val index: String? = null) { - - init { - if (body.isEmpty()) error("Syntax error: Name token body is empty") - } - - private fun String.escape() = - replace("\\", "\\\\") - .replace(".", "\\.") - .replace("[", "\\[") - .replace("]", "\\]") - - override fun toString(): String = if (hasIndex()) { - "${body.escape()}[$index]" - } else { - body.escape() - } - - @OptIn(ExperimentalSerializationApi::class) - @Serializer(NameToken::class) - public companion object : KSerializer { - override val descriptor: SerialDescriptor = - PrimitiveSerialDescriptor("hep.dataforge.names.NameToken", PrimitiveKind.STRING) - - override fun deserialize(decoder: Decoder): NameToken { - return decoder.decodeString().toName().firstOrNull()!! - } - - override fun serialize(encoder: Encoder, value: NameToken) { - encoder.encodeString(value.toString()) - } - } -} - -/** - * Check if index is defined for this token - */ -public fun NameToken.hasIndex(): Boolean = index != null - -/** - * Add or replace index part of this token - */ -public fun NameToken.withIndex(newIndex: String): NameToken = NameToken(body, newIndex) /** * Convert a [String] to name parsing it and extracting name tokens and index syntax. diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/NameToken.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/NameToken.kt new file mode 100644 index 00000000..d010ac5a --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/NameToken.kt @@ -0,0 +1,60 @@ +package hep.dataforge.names + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +/** + * A single name token. Body is not allowed to be empty. + * Following symbols are prohibited in name tokens: `{}.:\`. + * A name token could have appendix in square brackets called *index* + */ +@Serializable(NameToken.Companion::class) +public data class NameToken(val body: String, val index: String? = null) { + + init { + if (body.isEmpty()) error("Syntax error: Name token body is empty") + } + + private fun String.escape() = + replace("\\", "\\\\") + .replace(".", "\\.") + .replace("[", "\\[") + .replace("]", "\\]") + + override fun toString(): String = if (hasIndex()) { + "${body.escape()}[$index]" + } else { + body.escape() + } + + public companion object : KSerializer { + override val descriptor: SerialDescriptor = + PrimitiveSerialDescriptor("hep.dataforge.names.NameToken", PrimitiveKind.STRING) + + override fun deserialize(decoder: Decoder): NameToken { + return decoder.decodeString().toName().firstOrNull()!! + } + + override fun serialize( + encoder: Encoder, + value: NameToken, + ) { + encoder.encodeString(value.toString()) + } + } +} + +/** + * Check if index is defined for this token + */ +public fun NameToken.hasIndex(): Boolean = index != null + +/** + * Add or replace index part of this token + */ +public fun NameToken.withIndex(newIndex: String): NameToken = NameToken(body, newIndex) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/Value.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/Value.kt index 9136d525..ca78f0ae 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/Value.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/Value.kt @@ -19,6 +19,7 @@ public enum class ValueType { * * Value can represent a list of value objects. */ +@Serializable(ValueSerializer::class) public interface Value { /** * Get raw value of this value diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/ValueSerializer.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/ValueSerializer.kt index f7693646..08b87c18 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/ValueSerializer.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/ValueSerializer.kt @@ -1,8 +1,6 @@ package hep.dataforge.values -import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializer import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.buildClassSerialDescriptor @@ -10,8 +8,6 @@ import kotlinx.serialization.descriptors.element import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -@OptIn(ExperimentalSerializationApi::class) -@Serializer(Value::class) public object ValueSerializer : KSerializer { private val listSerializer by lazy { ListSerializer(ValueSerializer) } diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt index 925ee36c..6b8442d1 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt @@ -1,5 +1,6 @@ package hep.dataforge.meta +import hep.dataforge.values.asValue import kotlin.test.Test import kotlin.test.assertEquals @@ -29,7 +30,7 @@ class MetaDelegateTest { fun delegateTest() { val testObject = TestScheme.empty() - testObject.config["myValue"] = "theString" + testObject.setValue("myValue","theString".asValue()) testObject.enumValue = TestEnum.NO testObject.inner = InnerSpec { innerValue = "ddd" } diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt index e74c7bb3..bf73ba8c 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt @@ -9,10 +9,8 @@ class SpecificationTest { var list by numberList(1, 2, 3) companion object : Specification { - override fun wrap( - config: Config, - defaultProvider: ItemProvider - ): TestStyled = TestStyled(config, defaultProvider) + override fun wrap(meta: Meta, defaultProvider: ItemProvider): TestStyled = + TestStyled(meta.asConfig(), defaultProvider) } } diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableTable.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableTable.kt index 7a1e0376..f4070146 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableTable.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableTable.kt @@ -1,6 +1,7 @@ package hep.dataforge.tables import hep.dataforge.meta.Meta +import hep.dataforge.meta.invoke import hep.dataforge.values.Value import kotlin.reflect.KClass diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/numericColumns.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/numericColumns.kt index cc386c35..86868a22 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/numericColumns.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/numericColumns.kt @@ -1,6 +1,7 @@ package hep.dataforge.tables import hep.dataforge.meta.Meta +import hep.dataforge.meta.invoke import kotlin.reflect.KClass diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Dependency.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Dependency.kt index 10bf38d6..e58a988b 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Dependency.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Dependency.kt @@ -29,7 +29,7 @@ public class DataDependency(private val filter: DataFilter, private val placemen } override fun toMeta(): Meta = Meta { - "data" put filter.config + "data" put filter.toMeta() "to" put placement.toString() } }