Refactor Scheme and MutableItemProvider.kt

This commit is contained in:
Alexander Nozik 2020-11-10 19:08:53 +03:00
parent 8ef0b2247c
commit d5992c721d
28 changed files with 519 additions and 375 deletions

View File

@ -2,7 +2,7 @@ plugins {
id("ru.mipt.npm.project") 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 bintrayRepo by extra("dataforge")
val githubProject by extra("dataforge-core") val githubProject by extra("dataforge-core")

View File

@ -229,6 +229,35 @@ public abstract interface annotation class hep/dataforge/descriptors/ValueDef :
public abstract fun type ()[Lhep/dataforge/values/ValueType; public abstract fun type ()[Lhep/dataforge/values/ValueType;
} }
public final class hep/dataforge/properties/ConfigProperty : hep/dataforge/properties/Property {
public fun <init> (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 final class hep/dataforge/provider/DfTypeKt {
public static final fun getDfType (Lkotlin/reflect/KClass;)Ljava/lang/String; public static final fun getDfType (Lkotlin/reflect/KClass;)Ljava/lang/String;
} }

View File

@ -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<T : Any>(
public val config: Config,
public val name: Name,
public val converter: MetaConverter<T>,
) : Property<T?> {
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)
}
}

View File

@ -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<T> {
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 <T> Property<T>.toFlow(): StateFlow<T> = 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 <T> Property<T>.mirror(source: Property<T>, scope: CoroutineScope) {
source.onChange(this) {
this.value = it
}
}
/**
* Bi-directional connection between properties
*/
@DFExperimental
public fun <T> Property<T>.bind(other: Property<T>) {
onChange(other) {
other.value = it
}
other.onChange {
this.value = it
}
}

View File

@ -0,0 +1,32 @@
package hep.dataforge.properties
import hep.dataforge.meta.DFExperimental
import org.w3c.dom.HTMLInputElement
@DFExperimental
fun HTMLInputElement.bindValue(property: Property<String>) {
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<Boolean>) {
if (this.onchange != null) error("Input element already bound")
this.onchange = {
property.value = this.checked
Unit
}
property.onChange(this) {
if (checked != it) {
checked = it
}
}
}

View File

@ -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 getFrom ()Ljava/lang/String;
public final fun getPattern ()Ljava/lang/String; public final fun getPattern ()Ljava/lang/String;
public final fun getTo ()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 setFrom (Ljava/lang/String;)V
public final fun setPattern (Ljava/lang/String;)V public final fun setPattern (Ljava/lang/String;)V
public final fun setTo (Ljava/lang/String;)V public final fun setTo (Ljava/lang/String;)V

View File

@ -20,8 +20,6 @@ public class DataFilter : Scheme() {
// val prefix by string() // val prefix by string()
// val suffix by string() // val suffix by string()
public fun isEmpty(): Boolean = config.isEmpty()
public companion object : SchemeSpec<DataFilter>(::DataFilter) public companion object : SchemeSpec<DataFilter>(::DataFilter)
} }

View File

@ -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 abstract class hep/dataforge/meta/AbstractMutableMeta : hep/dataforge/meta/AbstractMetaNode, hep/dataforge/meta/MutableMeta {
public fun <init> ()V public fun <init> ()V
protected final fun getChildren ()Ljava/util/Map;
public fun getItems ()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 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 public fun setItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V
protected final fun wrapItem (Lhep/dataforge/meta/MetaItem;)Lhep/dataforge/meta/MetaItem; 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 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 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 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 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 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 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 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 { 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 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;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 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 { 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 Companion Lhep/dataforge/meta/Meta$Companion;
public static final field TYPE Ljava/lang/String; public static final field TYPE Ljava/lang/String;
public static final field VALUE_KEY 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 getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public abstract fun getItems ()Ljava/util/Map; public abstract fun getItems ()Ljava/util/Map;
public abstract fun hashCode ()I
public abstract fun toMeta ()Lhep/dataforge/meta/Meta; public abstract fun toMeta ()Lhep/dataforge/meta/Meta;
public abstract fun toString ()Ljava/lang/String;
} }
public final class hep/dataforge/meta/Meta$Companion { 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 abstract fun toMeta ()Lhep/dataforge/meta/Meta;
} }
public class hep/dataforge/meta/MetaScheme : hep/dataforge/meta/Scheme {
public fun <init> (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;Lhep/dataforge/meta/Config;)V
public synthetic fun <init> (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 final class hep/dataforge/meta/MetaSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Lhep/dataforge/meta/MetaSerializer; public static final field INSTANCE Lhep/dataforge/meta/MetaSerializer;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/meta/Meta; 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 synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
} }
public final class hep/dataforge/meta/MetaWithDefault : hep/dataforge/meta/MetaBase {
public fun <init> (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 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/properties/ReadWriteProperty;
public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)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 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 interface class hep/dataforge/meta/MutableMeta : hep/dataforge/meta/MetaNode, hep/dataforge/meta/MutableItemProvider {
public abstract fun getItems ()Ljava/util/Map; 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;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 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 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 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 class hep/dataforge/meta/Scheme : hep/dataforge/meta/Configurable, hep/dataforge/meta/MetaRepr, hep/dataforge/meta/descriptors/Described {
public fun <init> ()V public fun <init> ()V
public fun <init> (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)V public fun <init> (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V
public synthetic fun <init> (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 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 fun getDefaultLayer ()Lhep/dataforge/meta/Meta;
public final fun getDefaultProvider ()Lhep/dataforge/meta/ItemProvider;
public synthetic fun getDescriptor ()Lhep/dataforge/meta/descriptors/ItemDescriptor; public synthetic fun getDescriptor ()Lhep/dataforge/meta/descriptors/ItemDescriptor;
public fun getDescriptor ()Lhep/dataforge/meta/descriptors/NodeDescriptor; public fun getDescriptor ()Lhep/dataforge/meta/descriptors/NodeDescriptor;
public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; 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 setItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V
public fun toMeta ()Lhep/dataforge/meta/Laminate; public fun toMeta ()Lhep/dataforge/meta/Laminate;
public synthetic fun toMeta ()Lhep/dataforge/meta/Meta; 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 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 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 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; 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 class hep/dataforge/meta/SchemeSpec : hep/dataforge/meta/Specification {
public fun <init> (Lkotlin/jvm/functions/Function0;)V public fun <init> (Lkotlin/jvm/functions/Function0;)V
public fun <init> (Lkotlin/jvm/functions/Function2;)V public fun <init> (Lkotlin/jvm/functions/Function2;)V
public synthetic fun empty ()Lhep/dataforge/meta/Configurable; public synthetic fun wrap (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
public fun empty ()Lhep/dataforge/meta/Scheme; public fun wrap (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)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 final class hep/dataforge/meta/SealedMeta : hep/dataforge/meta/AbstractMetaNode { 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 interface class hep/dataforge/meta/Specification {
public abstract fun empty ()Lhep/dataforge/meta/Configurable; public abstract fun wrap (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
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 final class hep/dataforge/meta/Specification$DefaultImpls { public final class hep/dataforge/meta/Specification$DefaultImpls {
public static fun empty (Lhep/dataforge/meta/Specification;)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 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 final class hep/dataforge/meta/SpecificationKt { 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 configSpec (Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider;
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 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 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/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 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/Configurable; 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 { 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 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 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 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 isEmpty (Lhep/dataforge/names/Name;)Z
public static final fun lastOrNull (Lhep/dataforge/names/Name;)Lhep/dataforge/names/NameToken; 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; 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 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 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/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 { 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 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 final class hep/dataforge/values/DoubleArrayValue : hep/dataforge/values/Value {
public fun <init> ([D)V public fun <init> ([D)V
public fun equals (Ljava/lang/Object;)Z public fun equals (Ljava/lang/Object;)Z

View File

@ -1,16 +1,12 @@
import ru.mipt.npm.gradle.KScienceVersions
plugins { plugins {
id("ru.mipt.npm.mpp") id("ru.mipt.npm.mpp")
id("ru.mipt.npm.native") id("ru.mipt.npm.native")
} }
kscience { kscience {
useSerialization() useSerialization{
json()
}
} }
description = "Meta definition and basic operations on meta" description = "Meta definition and basic operations on meta"
dependencies{
commonMainApi("org.jetbrains.kotlinx:kotlinx-serialization-json:${KScienceVersions.serializationVersion}")
}

View File

@ -4,10 +4,8 @@ import hep.dataforge.names.Name
import hep.dataforge.names.NameToken import hep.dataforge.names.NameToken
import hep.dataforge.names.asName import hep.dataforge.names.asName
import hep.dataforge.names.plus import hep.dataforge.names.plus
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
@ -53,12 +51,12 @@ public class Config() : AbstractMutableMeta<Config>(), ObservableMeta {
override fun replaceItem(key: NameToken, oldItem: MetaItem<Config>?, newItem: MetaItem<Config>?) { override fun replaceItem(key: NameToken, oldItem: MetaItem<Config>?, newItem: MetaItem<Config>?) {
if (newItem == null) { if (newItem == null) {
_items.remove(key) children.remove(key)
if (oldItem != null && oldItem is MetaItem.NodeItem<Config>) { if (oldItem != null && oldItem is MetaItem.NodeItem<Config>) {
oldItem.node.removeListener(this) oldItem.node.removeListener(this)
} }
} else { } else {
_items[key] = newItem children[key] = newItem
if (newItem is MetaItem.NodeItem) { if (newItem is MetaItem.NodeItem) {
newItem.node.onChange(this) { name, oldChild, newChild -> newItem.node.onChange(this) { name, oldChild, newChild ->
itemChanged(key + name, oldChild, newChild) itemChanged(key + name, oldChild, newChild)
@ -75,8 +73,6 @@ public class Config() : AbstractMutableMeta<Config>(), ObservableMeta {
override fun empty(): Config = Config() override fun empty(): Config = Config()
@OptIn(ExperimentalSerializationApi::class)
@Serializer(Config::class)
public companion object ConfigSerializer : KSerializer<Config> { public companion object ConfigSerializer : KSerializer<Config> {
public fun empty(): Config = Config() public fun empty(): Config = Config()

View File

@ -1,67 +1,30 @@
package hep.dataforge.meta package hep.dataforge.meta
import hep.dataforge.meta.descriptors.*
import hep.dataforge.names.Name 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.properties.ReadWriteProperty
import kotlin.reflect.KProperty
/** /**
* A container that holds a [Config] and a default item provider. * A container that holds a [Config].
* 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.
*/ */
public interface Configurable : Described, MutableItemProvider { public interface Configurable : MutableItemProvider {
/** /**
* Backing config * Backing config
*/ */
public val config: 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 * Get a property with default
*/ */
override fun getItem(name: Name): MetaItem<*>? = override fun getItem(name: Name): MetaItem<*>? = config[name]
config[name] ?: getDefaultItem(name) ?: descriptor?.get(name)?.defaultItem()
/** /**
* Set a configurable property * Set a configurable property
*/ */
override fun setItem(name: Name, item: MetaItem<*>?) { override fun setItem(name: Name, item: MetaItem<*>?) {
if (validateItem(name, item)) {
config.setItem(name, item) config.setItem(name, item)
} else {
error("Validation failed for property $name with value $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 : Configurable> T.configure(meta: Meta): T = this.apply { config.update(meta) } public fun <T : Configurable> T.configure(meta: Meta): T = this.apply { config.update(meta) }
@ -70,39 +33,4 @@ public inline fun <T : Configurable> T.configure(action: Config.() -> Unit): T =
/* Node delegates */ /* Node delegates */
public fun Configurable.config(key: Name? = null): ReadWriteProperty<Any?, Config?> = public fun Configurable.config(key: Name? = null): ReadWriteProperty<Any?, Config?> = config.node(key)
config.node(key)
public fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty<Any?, Meta?> = item(key).convert(
reader = { it.node },
writer = { it?.let { MetaItem.NodeItem(it) } }
)
public fun <T : Configurable> Configurable.spec(
spec: Specification<T>, key: Name? = null
): ReadWriteProperty<Any?, T?> = object : ReadWriteProperty<Any?, T?> {
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 <T : Configurable> Configurable.spec(
spec: Specification<T>, default: T, key: Name? = null
): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> {
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
}
}

View File

@ -66,6 +66,7 @@ public fun <M : Meta> M.asMetaItem(): NodeItem<M> = NodeItem(this)
* The object that could be represented as [Meta]. Meta provided by [toMeta] method should fully represent object state. * 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. * Meaning that two states with the same meta are equal.
*/ */
@Serializable(MetaSerializer::class)
public interface MetaRepr { public interface MetaRepr {
public fun toMeta(): Meta public fun toMeta(): Meta
} }
@ -104,12 +105,11 @@ public interface Meta : MetaRepr, ItemProvider {
override fun toMeta(): Meta = seal() 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 equals(other: Any?): Boolean
// override fun hashCode(): Int
// override fun hashCode(): Int
// override fun toString(): String
// override fun toString(): String
public companion object { public companion object {
public const val TYPE: String = "meta" public const val TYPE: String = "meta"

View File

@ -68,7 +68,7 @@ public class MetaBuilder : AbstractMutableMeta<MetaBuilder>() {
@JvmName("putMetas") @JvmName("putMetas")
public infix fun String.put(value: Iterable<Meta>) { public infix fun String.put(value: Iterable<Meta>) {
this@MetaBuilder[this] = value.toList() set(this,value.toList())
} }
public infix fun String.put(metaBuilder: MetaBuilder.() -> Unit) { public infix fun String.put(metaBuilder: MetaBuilder.() -> Unit) {
@ -110,7 +110,7 @@ public class MetaBuilder : AbstractMutableMeta<MetaBuilder>() {
@JvmName("putMetas") @JvmName("putMetas")
public infix fun Name.put(value: Iterable<Meta>) { public infix fun Name.put(value: Iterable<Meta>) {
this@MetaBuilder[this] = value.toList() set(this, value.toList())
} }
public infix fun Name.put(metaBuilder: MetaBuilder.() -> Unit) { public infix fun Name.put(metaBuilder: MetaBuilder.() -> Unit) {

View File

@ -5,7 +5,6 @@ import hep.dataforge.values.ValueSerializer
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.InternalSerializationApi import kotlinx.serialization.InternalSerializationApi
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.MapSerializer import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.descriptors.* import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.* import kotlinx.serialization.encoding.*
@ -52,8 +51,6 @@ public object MetaItemSerializer : KSerializer<MetaItem<*>> {
/** /**
* Serialized for meta * Serialized for meta
*/ */
@OptIn(ExperimentalSerializationApi::class)
@Serializer(Meta::class)
public object MetaSerializer : KSerializer<Meta> { public object MetaSerializer : KSerializer<Meta> {
private val mapSerializer: KSerializer<Map<NameToken, MetaItem<Meta>>> = MapSerializer( private val mapSerializer: KSerializer<Map<NameToken, MetaItem<Meta>>> = MapSerializer(

View File

@ -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<NameToken, MetaItem<*>>
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)

View File

@ -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<Any?, Meta?> = 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<MetaItem<*>>,
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<Meta>,
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<Meta>): Unit = setIndexed(name, metas)
public operator fun MutableItemProvider.set(name: String, metas: Iterable<Meta>): Unit = setIndexed(name.toName(), metas)

View File

@ -1,11 +1,6 @@
package hep.dataforge.meta package hep.dataforge.meta
import hep.dataforge.names.* import hep.dataforge.names.*
import hep.dataforge.values.Value
public interface MutableItemProvider : ItemProvider {
public fun setItem(name: Name, item: MetaItem<*>?)
}
public interface MutableMeta<out M : MutableMeta<M>> : MetaNode<M>, MutableItemProvider { public interface MutableMeta<out M : MutableMeta<M>> : MetaNode<M>, MutableItemProvider {
override val items: Map<NameToken, MetaItem<M>> override val items: Map<NameToken, MetaItem<M>>
@ -19,18 +14,18 @@ public interface MutableMeta<out M : MutableMeta<M>> : MetaNode<M>, MutableItemP
* Changes in Meta are not thread safe. * Changes in Meta are not thread safe.
*/ */
public abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(), MutableMeta<M> { public abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(), MutableMeta<M> {
protected val _items: MutableMap<NameToken, MetaItem<M>> = LinkedHashMap() protected val children: MutableMap<NameToken, MetaItem<M>> = LinkedHashMap()
override val items: Map<NameToken, MetaItem<M>> override val items: Map<NameToken, MetaItem<M>>
get() = _items get() = children
//protected abstract fun itemChanged(name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) //protected abstract fun itemChanged(name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?)
protected open fun replaceItem(key: NameToken, oldItem: MetaItem<M>?, newItem: MetaItem<M>?) { protected open fun replaceItem(key: NameToken, oldItem: MetaItem<M>?, newItem: MetaItem<M>?) {
if (newItem == null) { if (newItem == null) {
_items.remove(key) children.remove(key)
} else { } else {
_items[key] = newItem children[key] = newItem
} }
//itemChanged(key.asName(), oldItem, newItem) //itemChanged(key.asName(), oldItem, newItem)
} }
@ -72,48 +67,6 @@ public abstract class AbstractMutableMeta<M : MutableMeta<M>> : 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: * Update existing mutable node with another node. The rules are following:
* * value replaces anything * * value replaces anything
@ -130,33 +83,6 @@ public fun <M : MutableMeta<M>> M.update(meta: Meta) {
} }
} }
/* Same name siblings generation */
public fun MutableMeta<*>.setIndexedItems(
name: Name,
items: Iterable<MetaItem<*>>,
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<Meta>,
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<Meta>): Unit = setIndexed(name, metas)
public operator fun MutableMeta<*>.set(name: String, metas: Iterable<Meta>): Unit = setIndexed(name.toName(), metas)
/** /**
* Append the node with a same-name-sibling, automatically generating numerical index * Append the node with a same-name-sibling, automatically generating numerical index
*/ */

View File

@ -1,31 +1,49 @@
package hep.dataforge.meta package hep.dataforge.meta
import hep.dataforge.meta.descriptors.Described import hep.dataforge.meta.descriptors.*
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.descriptors.defaultItem
import hep.dataforge.meta.descriptors.get
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.NameToken import hep.dataforge.names.NameToken
import hep.dataforge.names.asName import hep.dataforge.names.asName
/** /**
* A base for delegate-based or descriptor-based scheme. [Scheme] has an empty constructor to simplify usage from [Specification]. * 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( public open class Scheme(
config: Config, config: Config = Config(),
defaultProvider: ItemProvider, internal var default: ItemProvider? = null,
override val descriptor: NodeDescriptor? = null,
) : Configurable, Described, MetaRepr { ) : Configurable, Described, MetaRepr {
override var config: Config = config override var config: Config = config
internal set internal set
public var defaultProvider: ItemProvider = defaultProvider public fun getDefaultItem(name: Name): MetaItem<*>? {
internal set 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 if default value is unavailable.
* Values from [defaultProvider] completely replace * Values from [defaultProvider] completely replace
*/ */
public open val defaultLayer: Meta get() = DefaultLayer() public open val defaultLayer: Meta
get() = object : MetaBase() {
override fun toMeta(): Laminate = Laminate(config, defaultLayer)
private inner class DefaultLayer : MetaBase() {
override val items: Map<NameToken, MetaItem<*>> = buildMap { override val items: Map<NameToken, MetaItem<*>> = buildMap {
descriptor?.items?.forEach { (key, itemDescriptor) -> descriptor?.items?.forEach { (key, itemDescriptor) ->
val token = NameToken(key) val token = NameToken(key)
val name = token.asName() val name = token.asName()
val item = defaultProvider.getItem(name) ?: itemDescriptor.defaultItem() val item = default?.getItem(name) ?: itemDescriptor.defaultItem()
if (item != null) { if (item != null) {
put(token, item) put(token, item)
} }
} }
} }
} }
override fun toMeta(): Laminate = Laminate(config, defaultLayer)
public fun isEmpty(): Boolean = config.isEmpty()
} }
/** /**
@ -66,30 +85,32 @@ public open class SchemeSpec<T : Scheme>(
public constructor(emptyBuilder: () -> T) : this({ config: Config, defaultProvider: ItemProvider -> public constructor(emptyBuilder: () -> T) : this({ config: Config, defaultProvider: ItemProvider ->
emptyBuilder().apply { emptyBuilder().apply {
this.config = config 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)
}
/** /**
* A scheme that uses [Meta] as a default layer * If the provided [Meta] is a [Config] use it as a scheme base, otherwise use it as default.
*/ */
public open class MetaScheme( override fun wrap(meta: Meta, defaultProvider: ItemProvider): T = if (meta is Config) {
private val meta: Meta, builder(meta, defaultProvider)
override val descriptor: NodeDescriptor? = null, } else {
config: Config = Config(), builder(Config(), meta.withDefault(defaultProvider))
) : Scheme(config, meta) { }
override val defaultLayer: Meta get() = Laminate(meta, descriptor?.defaultItem().node)
} }
public fun Meta.asScheme(): MetaScheme = MetaScheme(this) ///**
// * 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(): Scheme = Scheme(this.asConfig(), null, null)
public fun <T : Configurable> Meta.toScheme(spec: Specification<T>, block: T.() -> Unit = {}): T = public fun <T : Configurable> Meta.toScheme(spec: Specification<T>, block: T.() -> Unit = {}): T =
spec.wrap(this).apply(block) spec.wrap(this).apply(block)

View File

@ -1,32 +1,36 @@
package hep.dataforge.meta package hep.dataforge.meta
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import kotlin.jvm.JvmName 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. * Allows to apply custom configuration in a type safe way to simple untyped configuration.
* By convention [Scheme] companion should inherit this class * By convention [Scheme] companion should inherit this class
* *
*/ */
public interface Specification<T : Configurable> { public interface Specification<T : MutableItemProvider> {
public fun empty(): T = wrap()
/** /**
* Wrap generic configuration producing instance of desired type * Wrap generic configuration producing instance of desired type
*/ */
public fun wrap(config: Config = Config(), defaultProvider: ItemProvider = ItemProvider{ null }): T public fun wrap(meta: Meta, defaultProvider: ItemProvider = ItemProvider.EMPTY): T
public operator fun invoke(action: T.() -> Unit): T = empty().apply(action)
} }
public operator fun <T : MutableItemProvider> Specification<T>.invoke(action: T.() -> Unit): T = empty().apply(action)
public fun <T : MutableItemProvider> Specification<T>.empty(): T = wrap(Config())
/** /**
* Update given configuration using given type as a builder * Update given configuration using given type as a builder
*/ */
public fun <T : Configurable> Specification<T>.update(config: Config, action: T.() -> Unit): T = wrap(config).apply(action) public fun <T : MutableItemProvider> Specification<T>.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 <T : Configurable> Specification<T>.wrap(source: Meta): T { public fun <T : MutableItemProvider> Specification<T>.wrap(source: Meta): T {
val default = source.seal() val default = source.seal()
return wrap(source.asConfig(), default) return wrap(source.asConfig(), default)
} }
@ -34,26 +38,56 @@ public fun <T : Configurable> Specification<T>.wrap(source: Meta): T {
/** /**
* Apply specified configuration to configurable * Apply specified configuration to configurable
*/ */
public fun <T : Configurable, C : Configurable, S : Specification<C>> T.configure(spec: S, action: C.() -> Unit): T = public fun <T : MetaRepr, C : MutableItemProvider, S : Specification<C>> T.configure(spec: S, action: C.() -> Unit): T =
apply { spec.update(config, action) } apply { spec.update(toMeta(), action) }
/** /**
* Update configuration using given specification * Update configuration using given specification
*/ */
public fun <C : Configurable, S : Specification<C>> Configurable.update(spec: S, action: C.() -> Unit): Configurable = public fun <C : MutableItemProvider, S : Specification<C>> Configurable.update(spec: S, action: C.() -> Unit): Configurable =
apply { spec.update(config, action) } apply { spec.update(config, action) }
/** /**
* Create a style based on given specification * Create a style based on given specification
*/ */
public fun <C : Configurable, S : Specification<C>> S.createStyle(action: C.() -> Unit): Meta = public fun <C : MutableItemProvider, S : Specification<C>> S.createStyle(action: C.() -> Unit): Meta =
Config().also { update(it, action) } Config().also { update(it, action) }
public fun <T : Configurable> MetaItem<*>.spec(spec: Specification<T>): T? = node?.let { public fun <T : MutableItemProvider> MetaItem<*>.spec(spec: Specification<T>): T? = node?.let {
spec.wrap( spec.wrap(
Config(), it Config(), it
) )
} }
@JvmName("configSpec") @JvmName("configSpec")
public fun <T : Configurable> MetaItem<Config>.spec(spec: Specification<T>): T? = node?.let { spec.wrap(it) } public fun <T : MutableItemProvider> MetaItem<Config>.spec(spec: Specification<T>): T? = node?.let { spec.wrap(it) }
public fun <T : Scheme> MutableItemProvider.spec(
spec: Specification<T>, key: Name? = null
): ReadWriteProperty<Any?, T?> = object : ReadWriteProperty<Any?, T?> {
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 <T : Scheme> MutableItemProvider.spec(
spec: Specification<T>,
default: T,
key: Name? = null
): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> {
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())
}
}

View File

@ -1,9 +1,7 @@
package hep.dataforge.names package hep.dataforge.names
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer
import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor 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`. * The name is a dot separated list of strings like `token1.token2.token3`.
* Each token could contain additional index in square brackets. * Each token could contain additional index in square brackets.
*/ */
@Serializable @Serializable(Name.Companion::class)
public class Name(public val tokens: List<NameToken>) { public class Name(public val tokens: List<NameToken>) {
//TODO to be transformed into inline class after they are supported with serialization //TODO to be transformed into inline class after they are supported with serialization
@ -38,8 +36,6 @@ public class Name(public val tokens: List<NameToken>) {
} }
} }
@OptIn(ExperimentalSerializationApi::class)
@Serializer(Name::class)
public companion object : KSerializer<Name> { public companion object : KSerializer<Name> {
public const val NAME_SEPARATOR: String = "." public const val NAME_SEPARATOR: String = "."
@ -82,55 +78,6 @@ public fun Name.lastOrNull(): NameToken? = tokens.lastOrNull()
*/ */
public fun Name.firstOrNull(): NameToken? = tokens.firstOrNull() 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<NameToken> {
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. * Convert a [String] to name parsing it and extracting name tokens and index syntax.

View File

@ -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<NameToken> {
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)

View File

@ -19,6 +19,7 @@ public enum class ValueType {
* *
* Value can represent a list of value objects. * Value can represent a list of value objects.
*/ */
@Serializable(ValueSerializer::class)
public interface Value { public interface Value {
/** /**
* Get raw value of this value * Get raw value of this value

View File

@ -1,8 +1,6 @@
package hep.dataforge.values package hep.dataforge.values
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.builtins.ListSerializer
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor import kotlinx.serialization.descriptors.buildClassSerialDescriptor
@ -10,8 +8,6 @@ import kotlinx.serialization.descriptors.element
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
@OptIn(ExperimentalSerializationApi::class)
@Serializer(Value::class)
public object ValueSerializer : KSerializer<Value> { public object ValueSerializer : KSerializer<Value> {
private val listSerializer by lazy { ListSerializer(ValueSerializer) } private val listSerializer by lazy { ListSerializer(ValueSerializer) }

View File

@ -1,5 +1,6 @@
package hep.dataforge.meta package hep.dataforge.meta
import hep.dataforge.values.asValue
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -29,7 +30,7 @@ class MetaDelegateTest {
fun delegateTest() { fun delegateTest() {
val testObject = TestScheme.empty() val testObject = TestScheme.empty()
testObject.config["myValue"] = "theString" testObject.setValue("myValue","theString".asValue())
testObject.enumValue = TestEnum.NO testObject.enumValue = TestEnum.NO
testObject.inner = InnerSpec { innerValue = "ddd" } testObject.inner = InnerSpec { innerValue = "ddd" }

View File

@ -9,10 +9,8 @@ class SpecificationTest {
var list by numberList(1, 2, 3) var list by numberList(1, 2, 3)
companion object : Specification<TestStyled> { companion object : Specification<TestStyled> {
override fun wrap( override fun wrap(meta: Meta, defaultProvider: ItemProvider): TestStyled =
config: Config, TestStyled(meta.asConfig(), defaultProvider)
defaultProvider: ItemProvider
): TestStyled = TestStyled(config, defaultProvider)
} }
} }

View File

@ -1,6 +1,7 @@
package hep.dataforge.tables package hep.dataforge.tables
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.invoke
import hep.dataforge.values.Value import hep.dataforge.values.Value
import kotlin.reflect.KClass import kotlin.reflect.KClass

View File

@ -1,6 +1,7 @@
package hep.dataforge.tables package hep.dataforge.tables
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.invoke
import kotlin.reflect.KClass import kotlin.reflect.KClass

View File

@ -29,7 +29,7 @@ public class DataDependency(private val filter: DataFilter, private val placemen
} }
override fun toMeta(): Meta = Meta { override fun toMeta(): Meta = Meta {
"data" put filter.config "data" put filter.toMeta()
"to" put placement.toString() "to" put placement.toString()
} }
} }