A major refactor MutableItemProvider instead of Config

This commit is contained in:
Alexander Nozik 2020-12-23 19:09:02 +03:00
parent 702589f7b3
commit 89f0d627b8
26 changed files with 379 additions and 351 deletions

View File

@ -2,7 +2,7 @@ plugins {
id("ru.mipt.npm.project")
}
val dataforgeVersion by extra("0.2.1-dev-5")
val dataforgeVersion by extra("0.2.1-dev-6")
val bintrayRepo by extra("dataforge")
val githubProject by extra("dataforge-core")

View File

@ -3,7 +3,7 @@ package hep.dataforge.context
import hep.dataforge.meta.Laminate
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaRepr
import hep.dataforge.meta.sequence
import hep.dataforge.meta.itemSequence
import hep.dataforge.names.Name
import hep.dataforge.provider.Provider
import kotlinx.coroutines.CoroutineScope
@ -47,13 +47,13 @@ public open class Context(
public fun content(target: String, inherit: Boolean): Map<Name, Any> {
return if (inherit) {
when (target) {
PROPERTY_TARGET -> properties.sequence().toMap()
PROPERTY_TARGET -> properties.itemSequence().toMap()
Plugin.TARGET -> plugins.list(true).associateBy { it.name }
else -> emptyMap()
}
} else {
when (target) {
PROPERTY_TARGET -> properties.layers.firstOrNull()?.sequence()?.toMap() ?: emptyMap()
PROPERTY_TARGET -> properties.layers.firstOrNull()?.itemSequence()?.toMap() ?: emptyMap()
Plugin.TARGET -> plugins.list(false).associateBy { it.name }
else -> emptyMap()
}

View File

@ -3,6 +3,7 @@ package hep.dataforge.properties
import hep.dataforge.meta.Config
import hep.dataforge.meta.DFExperimental
import hep.dataforge.meta.get
import hep.dataforge.meta.set
import hep.dataforge.meta.transformations.MetaConverter
import hep.dataforge.meta.transformations.nullableItemToObject
import hep.dataforge.meta.transformations.nullableObjectToMetaItem
@ -18,7 +19,7 @@ public class ConfigProperty<T : Any>(
override var value: T?
get() = converter.nullableItemToObject(config[name])
set(value) {
config.setItem(name,converter.nullableObjectToMetaItem(value))
config[name] = converter.nullableObjectToMetaItem(value)
}
override fun onChange(owner: Any?, callback: (T?) -> Unit) {

View File

@ -5,7 +5,7 @@ import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.setItem
import hep.dataforge.meta.set
import hep.dataforge.values.*
import kotlinx.io.*
import kotlinx.io.text.readUtf8String
@ -126,7 +126,7 @@ public object BinaryMetaFormat : MetaFormat, MetaFormatFactory {
(1..length).forEach { _ ->
val name = readString()
val item = readMetaItem()
setItem(name, item)
set(name, item)
}
}
MetaItem.NodeItem(meta)

View File

@ -10,13 +10,14 @@ import hep.dataforge.io.PartDescriptor.Companion.SEPARATOR_KEY
import hep.dataforge.meta.*
import hep.dataforge.names.asName
import hep.dataforge.names.plus
import hep.dataforge.names.toName
import kotlinx.io.Binary
import kotlinx.io.writeBinary
private class PartDescriptor : Scheme() {
var offset by int(0)
var size by int(0)
var meta by node()
var partMeta by node("meta".toName())
companion object : SchemeSpec<PartDescriptor>(::PartDescriptor) {
val MULTIPART_KEY = ENVELOPE_NODE_KEY + "multipart"
@ -48,7 +49,7 @@ public fun EnvelopeBuilder.multipart(
PartDescriptor {
offset = offsetCounter
size = binary.size
meta = description
partMeta = description
}.also {
offsetCounter += binary.size
}
@ -95,7 +96,7 @@ public fun Envelope.parts(): EnvelopeParts {
} else {
parts.map {
val binary = data!!.view(it.offset, it.size)
val meta = Laminate(it.meta, meta[MULTIPART_KEY].node)
val meta = Laminate(it.partMeta, meta[MULTIPART_KEY].node)
EnvelopePart(binary, meta)
}
}

View File

@ -1,10 +1,4 @@
public abstract class hep/dataforge/meta/AbstractMetaNode : hep/dataforge/meta/MetaBase, hep/dataforge/meta/MetaNode {
public fun <init> ()V
public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public fun toMeta ()Lhep/dataforge/meta/Meta;
}
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/AbstractTypedMeta, hep/dataforge/meta/MutableMeta {
public fun <init> ()V
protected final fun getChildren ()Ljava/util/Map;
public fun getItems ()Ljava/util/Map;
@ -14,6 +8,12 @@ public abstract class hep/dataforge/meta/AbstractMutableMeta : hep/dataforge/met
protected abstract fun wrapNode (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MutableMeta;
}
public abstract class hep/dataforge/meta/AbstractTypedMeta : hep/dataforge/meta/MetaBase, hep/dataforge/meta/TypedMeta {
public fun <init> ()V
public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public fun toMeta ()Lhep/dataforge/meta/Meta;
}
public final class hep/dataforge/meta/Config : hep/dataforge/meta/AbstractMutableMeta, hep/dataforge/meta/ObservableItemProvider {
public static final field ConfigSerializer Lhep/dataforge/meta/Config$ConfigSerializer;
public fun <init> ()V
@ -36,6 +36,7 @@ public final class hep/dataforge/meta/Config$ConfigSerializer : kotlinx/serializ
public final class hep/dataforge/meta/ConfigKt {
public static final fun asConfig (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Config;
public static final fun get (Lhep/dataforge/meta/Config;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/MetaItem;
public static final fun toConfig (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Config;
}
public abstract interface class hep/dataforge/meta/Configurable {
@ -58,8 +59,8 @@ public abstract interface annotation class hep/dataforge/meta/DFExperimental : j
public final class hep/dataforge/meta/GetIndexedKt {
public static final fun getIndexed (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/Name;)Ljava/util/Map;
public static final fun getIndexed (Lhep/dataforge/meta/Meta;Ljava/lang/String;)Ljava/util/Map;
public static final fun getIndexed (Lhep/dataforge/meta/MetaNode;Lhep/dataforge/names/Name;)Ljava/util/Map;
public static final fun getIndexed (Lhep/dataforge/meta/MetaNode;Ljava/lang/String;)Ljava/util/Map;
public static final fun getIndexed (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/Name;)Ljava/util/Map;
public static final fun getIndexed (Lhep/dataforge/meta/TypedMeta;Ljava/lang/String;)Ljava/util/Map;
}
public final class hep/dataforge/meta/ItemDelegateKt {
@ -131,6 +132,12 @@ public final class hep/dataforge/meta/ItemProvider$Companion {
public final fun getEMPTY ()Lhep/dataforge/meta/ItemProvider;
}
public final class hep/dataforge/meta/ItemProviderKt {
public static final fun get (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public static final fun get (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem;
public static final fun withDefault (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/ItemProvider;
}
public final class hep/dataforge/meta/JsonMeta : hep/dataforge/meta/MetaBase {
public static final field Companion Lhep/dataforge/meta/JsonMeta$Companion;
public static final field JSON_ARRAY_KEY Ljava/lang/String;
@ -286,24 +293,9 @@ public final class hep/dataforge/meta/MetaItem$ValueItem$Companion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}
public final class hep/dataforge/meta/MetaItemSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Lhep/dataforge/meta/MetaItemSerializer;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/meta/MetaItem;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lhep/dataforge/meta/MetaItem;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
}
public final class hep/dataforge/meta/MetaKt {
public final class hep/dataforge/meta/MetaItemKt {
public static final fun asMetaItem (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MetaItem$NodeItem;
public static final fun asMetaItem (Lhep/dataforge/values/Value;)Lhep/dataforge/meta/MetaItem$ValueItem;
public static final fun get (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public static final fun get (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/MetaItem;
public static final fun get (Lhep/dataforge/meta/Meta;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem;
public static final fun get (Lhep/dataforge/meta/MetaNode;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public static final fun get (Lhep/dataforge/meta/MetaNode;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/MetaItem;
public static final fun get (Lhep/dataforge/meta/MetaNode;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem;
public static final fun getBoolean (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Boolean;
public static final fun getDouble (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Double;
public static final fun getFloat (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Float;
@ -315,21 +307,26 @@ public final class hep/dataforge/meta/MetaKt {
public static final fun getString (Lhep/dataforge/meta/MetaItem;)Ljava/lang/String;
public static final fun getStringList (Lhep/dataforge/meta/MetaItem;)Ljava/util/List;
public static final fun getValue (Lhep/dataforge/meta/MetaItem;)Lhep/dataforge/values/Value;
}
public final class hep/dataforge/meta/MetaItemSerializer : kotlinx/serialization/KSerializer {
public static final field INSTANCE Lhep/dataforge/meta/MetaItemSerializer;
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/meta/MetaItem;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lhep/dataforge/meta/MetaItem;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
}
public final class hep/dataforge/meta/MetaKt {
public static final fun get (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/MetaItem;
public static final fun get (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public static final fun get (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/MetaItem;
public static final fun get (Lhep/dataforge/meta/TypedMeta;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem;
public static final fun isEmpty (Lhep/dataforge/meta/Meta;)Z
public static final fun itemSequence (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence;
public static final fun iterator (Lhep/dataforge/meta/Meta;)Ljava/util/Iterator;
public static final fun seal (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/SealedMeta;
public static final fun seal (Lhep/dataforge/meta/MetaItem;)Lhep/dataforge/meta/MetaItem;
public static final fun sequence (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence;
public static final fun values (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence;
}
public abstract interface class hep/dataforge/meta/MetaNode : hep/dataforge/meta/Meta {
public abstract fun getItems ()Ljava/util/Map;
}
public final class hep/dataforge/meta/MetaNode$DefaultImpls {
public static fun getItem (Lhep/dataforge/meta/MetaNode;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public static fun toMeta (Lhep/dataforge/meta/MetaNode;)Lhep/dataforge/meta/Meta;
public static final fun valueSequence (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence;
}
public abstract interface class hep/dataforge/meta/MetaRepr {
@ -389,6 +386,8 @@ public final class hep/dataforge/meta/MutableItemDelegateKt {
public static final fun long (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty;
public static synthetic fun long$default (Lhep/dataforge/meta/MutableItemProvider;JLhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty;
public static synthetic fun long$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty;
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 number (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty;
public static final fun number (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty;
public static final fun number (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/Number;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty;
@ -418,14 +417,16 @@ public abstract interface class hep/dataforge/meta/MutableItemProvider : hep/dat
}
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;Lhep/dataforge/meta/Meta;)V
public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V
public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lhep/dataforge/values/Value;)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;Lhep/dataforge/meta/Meta;)V
public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Lhep/dataforge/meta/MetaItem;)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
@ -433,14 +434,11 @@ public final class hep/dataforge/meta/MutableItemProviderKt {
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 static final fun update (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Meta;)V
public static final fun withDefault (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
}
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/MutableItemProvider, hep/dataforge/meta/TypedMeta {
public abstract fun getItems ()Ljava/util/Map;
}
@ -453,7 +451,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 update (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/meta/Meta;)V
}
public abstract interface class hep/dataforge/meta/ObservableItemProvider : hep/dataforge/meta/ItemProvider {
@ -461,21 +458,20 @@ public abstract interface class hep/dataforge/meta/ObservableItemProvider : hep/
public abstract fun removeListener (Ljava/lang/Object;)V
}
public class hep/dataforge/meta/Scheme : hep/dataforge/meta/Configurable, hep/dataforge/meta/MetaRepr, hep/dataforge/meta/MutableItemProvider, hep/dataforge/meta/descriptors/Described {
public class hep/dataforge/meta/Scheme : hep/dataforge/meta/MetaRepr, hep/dataforge/meta/MutableItemProvider, hep/dataforge/meta/descriptors/Described {
public fun <init> ()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 final fun getDefaultItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public fun <init> (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V
public synthetic fun <init> (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/descriptors/NodeDescriptor;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 fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public final fun getItems ()Lhep/dataforge/meta/MutableItemProvider;
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 final fun validateItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z
public fun validateItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z
}
public final class hep/dataforge/meta/SchemeKt {
@ -494,42 +490,51 @@ public class hep/dataforge/meta/SchemeSpec : hep/dataforge/meta/Specification, h
public fun getDescriptor ()Lhep/dataforge/meta/descriptors/NodeDescriptor;
public synthetic fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider;
public final fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Scheme;
public synthetic fun read (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
public fun read (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme;
public synthetic fun wrap (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
public fun wrap (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme;
public synthetic fun read (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
public fun read (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme;
public synthetic fun write (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
public fun write (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/AbstractTypedMeta {
public fun getItems ()Ljava/util/Map;
}
public final class hep/dataforge/meta/SealedMetaKt {
public static final fun seal (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/SealedMeta;
public static final fun seal (Lhep/dataforge/meta/MetaItem;)Lhep/dataforge/meta/MetaItem;
}
public abstract interface class hep/dataforge/meta/Specification {
public abstract fun empty ()Lhep/dataforge/meta/MutableItemProvider;
public abstract fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider;
public abstract fun read (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
public abstract fun wrap (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
public abstract fun read (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
public abstract fun write (Lhep/dataforge/meta/Config;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/MutableItemProvider;
public static fun invoke (Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider;
public static synthetic fun read$default (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lhep/dataforge/meta/MutableItemProvider;
public static fun wrap (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider;
public static synthetic fun wrap$default (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lhep/dataforge/meta/MutableItemProvider;
public static synthetic fun write$default (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Config;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/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/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/Config;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider;
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/Meta;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider;
public static final fun withSpec (Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider;
}
public abstract interface class hep/dataforge/meta/TypedMeta : hep/dataforge/meta/Meta {
public abstract fun getItems ()Ljava/util/Map;
}
public final class hep/dataforge/meta/TypedMeta$DefaultImpls {
public static fun getItem (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public static fun toMeta (Lhep/dataforge/meta/TypedMeta;)Lhep/dataforge/meta/Meta;
}
public abstract interface class hep/dataforge/meta/descriptors/Described {
@ -545,10 +550,11 @@ public final class hep/dataforge/meta/descriptors/DescriptorMetaKt {
public static final fun defaultMeta (Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Laminate;
}
public abstract class hep/dataforge/meta/descriptors/ItemDescriptor {
public abstract class hep/dataforge/meta/descriptors/ItemDescriptor : hep/dataforge/meta/Configurable {
public static final field Companion Lhep/dataforge/meta/descriptors/ItemDescriptor$Companion;
public static final field DEFAULT_INDEX_KEY Ljava/lang/String;
public synthetic fun <init> (Lhep/dataforge/meta/Config;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public abstract fun copy ()Lhep/dataforge/meta/descriptors/ItemDescriptor;
public final fun getAttributes ()Lhep/dataforge/meta/Config;
public final fun getConfig ()Lhep/dataforge/meta/Config;
public final fun getIndexKey ()Ljava/lang/String;
@ -578,6 +584,8 @@ public final class hep/dataforge/meta/descriptors/NodeDescriptor : hep/dataforge
public fun <init> ()V
public fun <init> (Lhep/dataforge/meta/Config;)V
public synthetic fun <init> (Lhep/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun copy ()Lhep/dataforge/meta/descriptors/ItemDescriptor;
public fun copy ()Lhep/dataforge/meta/descriptors/NodeDescriptor;
public final fun getDefault ()Lhep/dataforge/meta/Config;
public final fun getItems ()Ljava/util/Map;
public final fun getNodes ()Ljava/util/Map;
@ -602,6 +610,8 @@ public final class hep/dataforge/meta/descriptors/ValueDescriptor : hep/dataforg
public fun <init> (Lhep/dataforge/meta/Config;)V
public synthetic fun <init> (Lhep/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun allow ([Ljava/lang/Object;)V
public synthetic fun copy ()Lhep/dataforge/meta/descriptors/ItemDescriptor;
public fun copy ()Lhep/dataforge/meta/descriptors/ValueDescriptor;
public final fun default (Ljava/lang/Object;)V
public final fun getAllowedValues ()Ljava/util/List;
public final fun getDefault ()Lhep/dataforge/values/Value;

View File

@ -11,7 +11,7 @@ import kotlin.properties.ReadOnlyProperty
public typealias ItemDelegate = ReadOnlyProperty<Any?, MetaItem<*>?>
public fun ItemProvider.item(key: Name? = null): ItemDelegate = ReadOnlyProperty { _, property ->
getItem(key ?: property.name.asName())
get(key ?: property.name.asName())
}
//TODO add caching for sealed nodes

View File

@ -0,0 +1,37 @@
package hep.dataforge.meta
import hep.dataforge.meta.MetaItem.NodeItem
import hep.dataforge.names.Name
import hep.dataforge.names.NameToken
import hep.dataforge.names.toName
public fun interface ItemProvider {
//getItem used instead of get in order to provide extension freedom
public fun getItem(name: Name): MetaItem<*>?
public companion object {
public val EMPTY: ItemProvider = ItemProvider { null }
}
}
/* Get operations*/
/**
* Perform recursive item search using given [name]. Each [NameToken] is treated as a name in [Meta.items] of a parent node.
*
* If [name] is empty return current [Meta] as a [NodeItem]
*/
public operator fun ItemProvider?.get(name: Name): MetaItem<*>? = this?.getItem(name)
/**
* Parse [Name] from [key] using full name notation and pass it to [Meta.get]
*/
public operator fun ItemProvider?.get(key: String): MetaItem<*>? = get(key.toName())
/**
* Create a provider that uses given provider for default values if those are not found in this provider
*/
public fun ItemProvider.withDefault(default: ItemProvider): ItemProvider = ItemProvider {
this[it] ?: default[it]
}

View File

@ -1,64 +1,12 @@
package hep.dataforge.meta
import hep.dataforge.meta.Meta.Companion.VALUE_KEY
import hep.dataforge.meta.MetaItem.NodeItem
import hep.dataforge.meta.MetaItem.ValueItem
import hep.dataforge.names.*
import hep.dataforge.values.*
import kotlinx.serialization.Serializable
import hep.dataforge.values.Value
import kotlinx.serialization.json.Json
/**
* A member of the meta tree. Could be represented as one of following:
* * a [ValueItem] (leaf)
* * a [NodeItem] (node)
*/
@Serializable(MetaItemSerializer::class)
public sealed class MetaItem<out M : Meta>() {
abstract override fun equals(other: Any?): Boolean
abstract override fun hashCode(): Int
@Serializable(MetaItemSerializer::class)
public class ValueItem(public val value: Value) : MetaItem<Nothing>() {
override fun toString(): String = value.toString()
override fun equals(other: Any?): Boolean {
return this.value == (other as? ValueItem)?.value
}
override fun hashCode(): Int {
return value.hashCode()
}
}
@Serializable(MetaItemSerializer::class)
public class NodeItem<M : Meta>(public val node: M) : MetaItem<M>() {
//Fixing serializer for node could cause class cast problems, but it should not since Meta descendants are not serializeable
override fun toString(): String = node.toString()
override fun equals(other: Any?): Boolean = node == (other as? NodeItem<*>)?.node
override fun hashCode(): Int = node.hashCode()
}
public companion object {
public fun of(arg: Any?): MetaItem<*> {
return when (arg) {
null -> ValueItem(Null)
is MetaItem<*> -> arg
is Meta -> NodeItem(arg)
else -> ValueItem(Value.of(arg))
}
}
}
}
public fun Value.asMetaItem(): ValueItem = ValueItem(this)
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.
* Meaning that two states with the same meta are equal.
@ -68,14 +16,6 @@ public interface MetaRepr {
public fun toMeta(): Meta
}
public fun interface ItemProvider {
public fun getItem(name: Name): MetaItem<*>?
public companion object {
public val EMPTY: ItemProvider = ItemProvider { null }
}
}
/**
* Generic meta tree representation. Elements are [MetaItem] objects that could be represented by three different entities:
* * [MetaItem.ValueItem] (leaf)
@ -100,7 +40,7 @@ public interface Meta : MetaRepr, ItemProvider {
}
}
override fun toMeta(): Meta = seal()
override fun toMeta(): Meta = this
override fun equals(other: Any?): Boolean
@ -122,30 +62,16 @@ public interface Meta : MetaRepr, ItemProvider {
}
}
/* Get operations*/
/**
* Perform recursive item search using given [name]. Each [NameToken] is treated as a name in [Meta.items] of a parent node.
*
* If [name] is empty return current [Meta] as a [NodeItem]
*/
public operator fun Meta?.get(name: Name): MetaItem<*>? = this?.getItem(name)
public operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token)
/**
* Parse [Name] from [key] using full name notation and pass it to [Meta.get]
*/
public operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName())
/**
* Get a sequence of [Name]-[Value] pairs
*/
public fun Meta.values(): Sequence<Pair<Name, Value>> {
public fun Meta.valueSequence(): Sequence<Pair<Name, Value>> {
return items.asSequence().flatMap { (key, item) ->
when (item) {
is ValueItem -> sequenceOf(key.asName() to item.value)
is NodeItem -> item.node.values().map { pair -> (key.asName() + pair.first) to pair.second }
is NodeItem -> item.node.valueSequence().map { pair -> (key.asName() + pair.first) to pair.second }
}
}
}
@ -153,41 +79,38 @@ public fun Meta.values(): Sequence<Pair<Name, Value>> {
/**
* Get a sequence of all [Name]-[MetaItem] pairs for all items including nodes
*/
public fun Meta.sequence(): Sequence<Pair<Name, MetaItem<*>>> {
return sequence {
items.forEach { (key, item) ->
yield(key.asName() to item)
if (item is NodeItem<*>) {
yieldAll(item.node.sequence().map { (innerKey, innerItem) ->
(key + innerKey) to innerItem
})
}
public fun Meta.itemSequence(): Sequence<Pair<Name, MetaItem<*>>> = sequence {
items.forEach { (key, item) ->
yield(key.asName() to item)
if (item is NodeItem<*>) {
yieldAll(item.node.itemSequence().map { (innerKey, innerItem) ->
(key + innerKey) to innerItem
})
}
}
}
public operator fun Meta.iterator(): Iterator<Pair<Name, MetaItem<*>>> = sequence().iterator()
public operator fun Meta.iterator(): Iterator<Pair<Name, MetaItem<*>>> = itemSequence().iterator()
/**
* A meta node that ensures that all of its descendants has at least the same type
*/
public interface MetaNode<out M : MetaNode<M>> : Meta {
public interface TypedMeta<out M : TypedMeta<M>> : Meta {
override val items: Map<NameToken, MetaItem<M>>
}
/**
* The same as [Meta.get], but with specific node type
*/
public operator fun <M : MetaNode<M>> M?.get(name: Name): MetaItem<M>? = if (this == null) {
public operator fun <M : TypedMeta<M>> M?.get(name: Name): MetaItem<M>? = if (this == null) {
null
} else {
@Suppress("UNCHECKED_CAST", "ReplaceGetOrSet")
(this as Meta).get(name) as MetaItem<M>? // Do not change
}
public operator fun <M : MetaNode<M>> M?.get(key: String): MetaItem<M>? = this[key.toName()]
public operator fun <M : MetaNode<M>> M?.get(key: NameToken): MetaItem<M>? = this[key.asName()]
public operator fun <M : TypedMeta<M>> M?.get(key: String): MetaItem<M>? = this[key.toName()]
public operator fun <M : TypedMeta<M>> M?.get(key: NameToken): MetaItem<M>? = this[key.asName()]
/**
* Equals, hashcode and to string for any meta
@ -211,57 +134,6 @@ public abstract class MetaBase : Meta {
/**
* Equals and hash code implementation for meta node
*/
public abstract class AbstractMetaNode<M : MetaNode<M>> : MetaNode<M>, MetaBase()
/**
* The meta implementation which is guaranteed to be immutable.
*
* If the argument is possibly mutable node, it is copied on creation
*/
public class SealedMeta internal constructor(
override val items: Map<NameToken, MetaItem<SealedMeta>>,
) : AbstractMetaNode<SealedMeta>()
/**
* Generate sealed node from [this]. If it is already sealed return it as is
*/
public fun Meta.seal(): SealedMeta = this as? SealedMeta ?: SealedMeta(items.mapValues { entry -> entry.value.seal() })
@Suppress("UNCHECKED_CAST")
public fun MetaItem<*>.seal(): MetaItem<SealedMeta> = when (this) {
is ValueItem -> this
is NodeItem -> NodeItem(node.seal())
}
/**
* Unsafe methods to access values and nodes directly from [MetaItem]
*/
public val MetaItem<*>?.value: Value?
get() = (this as? ValueItem)?.value
?: (this?.node?.get(VALUE_KEY) as? ValueItem)?.value
public val MetaItem<*>?.string: String? get() = value?.string
public val MetaItem<*>?.boolean: Boolean? get() = value?.boolean
public val MetaItem<*>?.number: Number? get() = value?.numberOrNull
public val MetaItem<*>?.double: Double? get() = number?.toDouble()
public val MetaItem<*>?.float: Float? get() = number?.toFloat()
public val MetaItem<*>?.int: Int? get() = number?.toInt()
public val MetaItem<*>?.long: Long? get() = number?.toLong()
public val MetaItem<*>?.short: Short? get() = number?.toShort()
public inline fun <reified E : Enum<E>> MetaItem<*>?.enum(): E? = if (this is ValueItem && this.value is EnumValue<*>) {
this.value.value as E
} else {
string?.let { enumValueOf<E>(it) }
}
public val MetaItem<*>.stringList: List<String>? get() = value?.list?.map { it.string }
public val <M : Meta> MetaItem<M>?.node: M?
get() = when (this) {
null -> null
is ValueItem -> null//error("Trying to interpret value meta item as node item")
is NodeItem -> node
}
public abstract class AbstractTypedMeta<M : TypedMeta<M>> : TypedMeta<M>, MetaBase()
public fun Meta.isEmpty(): Boolean = this === Meta.EMPTY || this.items.isEmpty()

View File

@ -0,0 +1,87 @@
package hep.dataforge.meta
import hep.dataforge.meta.MetaItem.NodeItem
import hep.dataforge.meta.MetaItem.ValueItem
import hep.dataforge.values.*
/**
* A member of the meta tree. Could be represented as one of following:
* * a [ValueItem] (leaf)
* * a [NodeItem] (node)
*/
@Serializable(MetaItemSerializer::class)
public sealed class MetaItem<out M : Meta>() {
abstract override fun equals(other: Any?): Boolean
abstract override fun hashCode(): Int
@Serializable(MetaItemSerializer::class)
public class ValueItem(public val value: Value) : MetaItem<Nothing>() {
override fun toString(): String = value.toString()
override fun equals(other: Any?): Boolean {
return this.value == (other as? ValueItem)?.value
}
override fun hashCode(): Int {
return value.hashCode()
}
}
@Serializable(MetaItemSerializer::class)
public class NodeItem<M : Meta>(public val node: M) : MetaItem<M>() {
//Fixing serializer for node could cause class cast problems, but it should not since Meta descendants are not serializeable
override fun toString(): String = node.toString()
override fun equals(other: Any?): Boolean = node == (other as? NodeItem<*>)?.node
override fun hashCode(): Int = node.hashCode()
}
public companion object {
public fun of(arg: Any?): MetaItem<*> {
return when (arg) {
null -> ValueItem(Null)
is MetaItem<*> -> arg
is Meta -> NodeItem(arg)
else -> ValueItem(Value.of(arg))
}
}
}
}
public fun Value.asMetaItem(): MetaItem.ValueItem = MetaItem.ValueItem(this)
public fun <M : Meta> M.asMetaItem(): MetaItem.NodeItem<M> = MetaItem.NodeItem(this)
/**
* Unsafe methods to access values and nodes directly from [MetaItem]
*/
public val MetaItem<*>?.value: Value?
get() = (this as? MetaItem.ValueItem)?.value
?: (this?.node?.get(Meta.VALUE_KEY) as? MetaItem.ValueItem)?.value
public val MetaItem<*>?.string: String? get() = value?.string
public val MetaItem<*>?.boolean: Boolean? get() = value?.boolean
public val MetaItem<*>?.number: Number? get() = value?.numberOrNull
public val MetaItem<*>?.double: Double? get() = number?.toDouble()
public val MetaItem<*>?.float: Float? get() = number?.toFloat()
public val MetaItem<*>?.int: Int? get() = number?.toInt()
public val MetaItem<*>?.long: Long? get() = number?.toLong()
public val MetaItem<*>?.short: Short? get() = number?.toShort()
public inline fun <reified E : Enum<E>> MetaItem<*>?.enum(): E? = if (this is MetaItem.ValueItem && this.value is EnumValue<*>) {
this.value.value as E
} else {
string?.let { enumValueOf<E>(it) }
}
public val MetaItem<*>.stringList: List<String>? get() = value?.list?.map { it.string }
public val <M : Meta> MetaItem<M>?.node: M?
get() = when (this) {
null -> null
is MetaItem.ValueItem -> null//error("Trying to interpret value meta item as node item")
is MetaItem.NodeItem -> node
}

View File

@ -11,7 +11,7 @@ public class MetaWithDefault(public val meta: Meta, public val default: ItemProv
get() = meta.items
override fun getItem(name: Name): MetaItem<*>? {
return meta[name] ?: default.getItem(name)
return meta[name] ?: default[name]
}
}

View File

@ -13,12 +13,12 @@ public typealias MutableItemDelegate = ReadWriteProperty<Any?, MetaItem<*>?>
public fun MutableItemProvider.item(key: Name? = null): MutableItemDelegate = object : MutableItemDelegate {
override fun getValue(thisRef: Any?, property: KProperty<*>): MetaItem<*>? {
return getItem(key ?: property.name.asName())
return get(key ?: property.name.asName())
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: MetaItem<*>?) {
val name = key ?: property.name.asName()
setItem(name, value)
set(name, value)
}
}
@ -113,6 +113,11 @@ public inline fun <reified E : Enum<E>> MutableItemProvider.enum(
): ReadWriteProperty<Any?, E> =
item(key).convert(MetaConverter.enum()) { default }
public fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty<Any?, Meta?> = item(key).convert(
reader = { it.node },
writer = { it?.asMetaItem() }
)
public inline fun <reified M : MutableMeta<M>> M.node(key: Name? = null): ReadWriteProperty<Any?, M?> =
item(key).convert(reader = { it?.let { it.node as M } }, writer = { it?.let { MetaItem.NodeItem(it) } })

View File

@ -2,32 +2,20 @@ 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 operator fun MutableItemProvider.set(name: Name, item: MetaItem<*>?): Unit = setItem(name, item)
public fun MutableItemProvider.setValue(name: Name, value: Value?): Unit =
setItem(name, value?.let { MetaItem.ValueItem(value) })
public operator fun MutableItemProvider.set(name: Name, value: Value?): Unit = set(name, value?.asMetaItem())
public fun MutableItemProvider.setNode(name: Name, meta: Meta?): Unit =
setItem(name, meta?.let { MetaItem.NodeItem(meta) })
public operator fun MutableItemProvider.set(name: Name, meta: Meta?): Unit = set(name, meta?.asMetaItem())
public fun MutableItemProvider.setItem(key: String, item: MetaItem<*>?): Unit = setItem(key.toName(), item)
public operator fun MutableItemProvider.set(key: String, item: MetaItem<*>?): Unit = set(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) } }
)
public operator fun MutableItemProvider.set(key: String, meta: Meta?): Unit = set(key, meta?.asMetaItem())
@Suppress("NOTHING_TO_INLINE")
public inline fun MutableItemProvider.remove(name: Name): Unit = setItem(name, null)
@ -35,17 +23,16 @@ public inline fun MutableItemProvider.remove(name: Name): Unit = setItem(name, n
@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))
is MetaItem<*> -> set(name, value)
is Meta -> set(name, value)
is Configurable -> set(name, value.config)
else -> set(name, Value.of(value))
}
}
@ -59,30 +46,56 @@ public operator fun MutableItemProvider.set(key: String, index: String, value: A
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() }
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)
set(Name(tokens), meta)
}
}
public fun MutableItemProvider.setIndexed(
name: Name,
metas: Iterable<Meta>,
indexFactory: (Meta, index: Int) -> String = { _, index -> index.toString() }
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)
public operator fun MutableItemProvider.set(name: String, metas: Iterable<Meta>): Unit =
setIndexed(name.toName(), metas)
/**
* Update existing mutable node with another node. The rules are following:
* * value replaces anything
* * node updates node and replaces anything but node
* * node list updates node list if number of nodes in the list is the same and replaces anything otherwise
*/
public fun MutableItemProvider.update(meta: Meta) {
meta.valueSequence().forEach { (name, value) -> set(name, value) }
}
/**
* Create a mutable item provider that uses given provider for default values if those are not found in this provider.
* Changes are propagated only to this provider.
*/
public fun MutableItemProvider.withDefault(default: ItemProvider): MutableItemProvider =
if (default is Meta && default.isEmpty()) {
//Optimize for use with empty default
this
} else object : MutableItemProvider {
override fun setItem(name: Name, item: MetaItem<*>?) {
this@withDefault.setItem(name, item)
}
override fun getItem(name: Name): MetaItem<*>? = this@withDefault.getItem(name) ?: default.getItem(name)
}

View File

@ -2,7 +2,7 @@ package hep.dataforge.meta
import hep.dataforge.names.*
public interface MutableMeta<out M : MutableMeta<M>> : MetaNode<M>, MutableItemProvider {
public interface MutableMeta<out M : MutableMeta<M>> : TypedMeta<M>, MutableItemProvider {
override val items: Map<NameToken, MetaItem<M>>
}
@ -11,7 +11,7 @@ public interface MutableMeta<out M : MutableMeta<M>> : MetaNode<M>, MutableItemP
*
* 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>> : AbstractTypedMeta<M>(), MutableMeta<M> {
protected val children: MutableMap<NameToken, MetaItem<M>> = LinkedHashMap()
override val items: Map<NameToken, MetaItem<M>>
@ -50,7 +50,7 @@ public abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode
0 -> error("Can't setValue meta item for empty name")
1 -> {
val token = name.firstOrNull()!!
@Suppress("UNCHECKED_CAST") val oldItem: MetaItem<M>? = get(name) as? MetaItem<M>
@Suppress("UNCHECKED_CAST") val oldItem: MetaItem<M>? = getItem(name) as? MetaItem<M>
replaceItem(token, oldItem, wrapItem(item))
}
else -> {
@ -59,28 +59,12 @@ public abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode
if (items[token] == null) {
replaceItem(token, null, MetaItem.NodeItem(empty()))
}
items[token]?.node!!.setItem(name.cutFirst(), item)
items[token]?.node!!.set(name.cutFirst(), item)
}
}
}
}
/**
* Update existing mutable node with another node. The rules are following:
* * value replaces anything
* * node updates node and replaces anything but node
* * node list updates node list if number of nodes in the list is the same and replaces anything otherwise
*/
public fun <M : MutableMeta<M>> M.update(meta: Meta) {
meta.items.forEach { entry ->
when (val value = entry.value) {
is MetaItem.ValueItem -> setValue(entry.key.asName(), value.value)
is MetaItem.NodeItem -> (this[entry.key.asName()] as? MetaItem.NodeItem)?.node?.update(value.node)
?: run { setNode(entry.key.asName(), value.node) }
}
}
}
/**
* Append the node with a same-name-sibling, automatically generating numerical index
*/

View File

@ -10,34 +10,34 @@ import hep.dataforge.names.asName
* Default item provider and [NodeDescriptor] are optional
*/
public open class Scheme(
config: Config = Config(),
items: MutableItemProvider = Config(),
internal var default: ItemProvider? = null,
descriptor: NodeDescriptor? = null,
) : Configurable, MutableItemProvider, Described, MetaRepr {
) : MutableItemProvider, Described, MetaRepr {
override var config: Config = config
public var items: MutableItemProvider = items
internal set(value) {
//Fix problem with `init` blocks in specifications
field = value.apply { update(field) }
field = value.withDefault(field)
}
override var descriptor: NodeDescriptor? = descriptor
internal set
public fun getDefaultItem(name: Name): MetaItem<*>? {
return default?.getItem(name) ?: descriptor?.get(name)?.defaultItem()
private fun getDefaultItem(name: Name): MetaItem<*>? {
return default?.get(name) ?: descriptor?.get(name)?.defaultItem()
}
/**
* Get a property with default
*/
override fun getItem(name: Name): MetaItem<*>? = config[name] ?: getDefaultItem(name)
override fun getItem(name: Name): MetaItem<*>? = items[name] ?: getDefaultItem(name)
/**
* Check if property with given [name] could be assigned to [item]
*/
public fun validateItem(name: Name, item: MetaItem<*>?): Boolean {
public open fun validateItem(name: Name, item: MetaItem<*>?): Boolean {
val descriptor = descriptor?.get(name)
return descriptor?.validateItem(item) ?: true
}
@ -47,16 +47,16 @@ public open class Scheme(
*/
override fun setItem(name: Name, item: MetaItem<*>?) {
if (validateItem(name, item)) {
config.setItem(name, item)
items[name] = item
} else {
error("Validation failed for property $name with value $item")
}
}
/**
* Provide a default layer which returns items from [defaultProvider] and falls back to descriptor
* Provide a default layer which returns items from [default] and falls back to descriptor
* values if default value is unavailable.
* Values from [defaultProvider] completely replace
* Values from [default] completely replace
*/
public open val defaultLayer: Meta
get() = object : MetaBase() {
@ -64,7 +64,7 @@ public open class Scheme(
descriptor?.items?.forEach { (key, itemDescriptor) ->
val token = NameToken(key)
val name = token.asName()
val item = default?.getItem(name) ?: itemDescriptor.defaultItem()
val item = default?.get(name) ?: itemDescriptor.defaultItem()
if (item != null) {
put(token, item)
}
@ -72,9 +72,9 @@ public open class Scheme(
}
}
override fun toMeta(): Laminate = Laminate(config, defaultLayer)
override fun toMeta(): Laminate = Laminate(items[Name.EMPTY].node, defaultLayer)
public fun isEmpty(): Boolean = config.isEmpty()
public fun isEmpty(): Boolean = toMeta().isEmpty()
}
/**
@ -91,18 +91,17 @@ public open class SchemeSpec<T : Scheme>(
public constructor(emptyBuilder: () -> T) : this({ config: Config, defaultProvider: ItemProvider, descriptor: NodeDescriptor? ->
emptyBuilder().apply {
this.config = config
this.items = config
this.default = defaultProvider
this.descriptor = descriptor
}
})
override fun read(meta: Meta, defaultProvider: ItemProvider): T =
builder(Config(), meta.withDefault(defaultProvider), descriptor)
override fun read(items: ItemProvider): T =
builder(Config(), items, descriptor)
override fun wrap(config: Config, defaultProvider: ItemProvider): T {
return builder(config, defaultProvider, descriptor)
}
override fun write(config: Config, defaultProvider: ItemProvider): T =
builder(config, defaultProvider, descriptor)
//TODO Generate descriptor from Scheme class
override val descriptor: NodeDescriptor? get() = null
@ -123,7 +122,7 @@ public open class SchemeSpec<T : Scheme>(
//}
public fun Meta.asScheme(): Scheme = Scheme().apply {
config = this@asScheme.asConfig()
items = this@asScheme.asConfig()
}
public fun <T : MutableItemProvider> Meta.toScheme(spec: Specification<T>, block: T.() -> Unit = {}): T =

View File

@ -0,0 +1,23 @@
package hep.dataforge.meta
import hep.dataforge.names.NameToken
/**
* The meta implementation which is guaranteed to be immutable.
*
* If the argument is possibly mutable node, it is copied on creation
*/
public class SealedMeta internal constructor(
override val items: Map<NameToken, MetaItem<SealedMeta>>,
) : AbstractTypedMeta<SealedMeta>()
/**
* Generate sealed node from [this]. If it is already sealed return it as is
*/
public fun Meta.seal(): SealedMeta = this as? SealedMeta ?: SealedMeta(items.mapValues { entry -> entry.value.seal() })
@Suppress("UNCHECKED_CAST")
public fun MetaItem<*>.seal(): MetaItem<SealedMeta> = when (this) {
is MetaItem.ValueItem -> this
is MetaItem.NodeItem -> MetaItem.NodeItem(node.seal())
}

View File

@ -2,7 +2,6 @@ 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
@ -15,13 +14,12 @@ public interface Specification<T : MutableItemProvider> {
/**
* Read generic read-only meta with this [Specification] producing instance of desired type.
*/
public fun read(meta: Meta, defaultProvider: ItemProvider = ItemProvider.EMPTY): T
public fun read(items: ItemProvider): T
/**
* Wrap mutable [Config], using it as inner storage (changes to [Specification] are reflected on [Config]
* Wrap [MutableItemProvider], using it as inner storage (changes to [Specification] are reflected on [MutableItemProvider]
*/
public fun wrap(config: Config, defaultProvider: ItemProvider = ItemProvider.EMPTY): T =
read(config as Meta, defaultProvider)
public fun write(config: Config, defaultProvider: ItemProvider = ItemProvider.EMPTY): T
/**
* Generate an empty object
@ -35,17 +33,10 @@ public interface Specification<T : MutableItemProvider> {
}
/**
* Update given configuration using given type as a builder
* Update a [Config] using given specification
*/
public fun <T : MutableItemProvider> Specification<T>.update(meta: Meta, action: T.() -> Unit): T =
read(meta).apply(action)
/**
* Apply specified configuration to configurable
*/
public fun <T : MetaRepr, C : MutableItemProvider, S : Specification<C>> T.configure(spec: S, action: C.() -> Unit): T =
apply { spec.update(toMeta(), action) }
public fun <T : MutableItemProvider> Config.update(spec: Specification<T>, action: T.() -> Unit): T =
spec.write(this).apply(action)
/**
* Update configuration using given specification
@ -53,35 +44,23 @@ public fun <T : MetaRepr, C : MutableItemProvider, S : Specification<C>> T.confi
public fun <C : MutableItemProvider, S : Specification<C>> Configurable.update(
spec: S,
action: C.() -> Unit,
): Configurable =
apply { spec.update(config, action) }
): Configurable = apply { config.update(spec, action) }
/**
* Create a style based on given specification
*/
public fun <C : MutableItemProvider, S : Specification<C>> S.createStyle(action: C.() -> Unit): Meta =
Config().also { update(it, action) }
public fun <T : MutableItemProvider> MetaItem<*>.spec(spec: Specification<T>): T? = node?.let {
spec.wrap(
Config(), it
)
}
@JvmName("configSpec")
public fun <T : MutableItemProvider> MetaItem<Config>.spec(spec: Specification<T>): T? = node?.let { spec.wrap(it) }
public fun <T : MutableItemProvider> MetaItem<Config>.withSpec(spec: Specification<T>): T? =
node?.let { spec.write(it) }
public fun <T : Scheme> MutableItemProvider.spec(
spec: Specification<T>, key: Name? = null,
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.read(it) }
return get(name).node?.let { spec.read(it) }
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
val name = key ?: property.name.asName()
setItem(name, value?.toMeta()?.asMetaItem())
set(name, value?.toMeta()?.asMetaItem())
}
}
@ -92,11 +71,11 @@ public fun <T : Scheme> MutableItemProvider.spec(
): 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.read(it) } ?: default
return get(name).node?.let { spec.read(it) } ?: default
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
val name = key ?: property.name.asName()
setItem(name, value.toMeta().asMetaItem())
set(name, value.toMeta().asMetaItem())
}
}

View File

@ -8,7 +8,7 @@ import hep.dataforge.values.*
* A common parent for [ValueDescriptor] and [NodeDescriptor]. Describes a single [MetaItem] or a group of same-name-siblings.
*/
@DFBuilder
public sealed class ItemDescriptor(public val config: Config) {
public sealed class ItemDescriptor(final override val config: Config): Configurable {
/**
* True if same name siblings with this name are allowed

View File

@ -0,0 +1,18 @@
package hep.dataforge.meta.descriptors
import hep.dataforge.names.Name
import hep.dataforge.values.ValueType
import hep.dataforge.values.asValue
public inline fun <reified E : Enum<E>> NodeDescriptor.enum(
key: Name,
default: E?,
crossinline modifier: ValueDescriptor.() -> Unit = {},
): Unit = value(key) {
type(ValueType.STRING)
default?.let {
default(default)
}
allowedValues = enumValues<E>().map { it.asValue() }
modifier()
}

View File

@ -29,8 +29,8 @@ public fun Meta.getIndexed(name: String): Map<String?, MetaItem<*>> = this@getIn
* Get all items matching given name.
*/
@Suppress("UNCHECKED_CAST")
public fun <M : MetaNode<M>> M.getIndexed(name: Name): Map<String, MetaItem<M>> =
public fun <M : TypedMeta<M>> M.getIndexed(name: Name): Map<String, MetaItem<M>> =
(this as Meta).getIndexed(name) as Map<String, MetaItem<M>>
public fun <M : MetaNode<M>> M.getIndexed(name: String): Map<String, MetaItem<M>> =
public fun <M : TypedMeta<M>> M.getIndexed(name: String): Map<String, MetaItem<M>> =
getIndexed(name.toName())

View File

@ -35,12 +35,12 @@ public fun Map<String, Any?>.toMeta(descriptor: NodeDescriptor? = null): Meta =
if (value is List<*>) {
val items = value.map { toItem(it) }
if (items.all { it is MetaItem.ValueItem }) {
setValue(key, ListValue(items.map { it.value!! }))
set(key, ListValue(items.map { it.value!! }))
} else {
setIndexedItems(key.toName(), value.map { toItem(it) })
}
} else {
setItem(key, toItem(value))
set(key, toItem(value))
}
}
}

View File

@ -19,7 +19,7 @@ public interface TransformationRule {
* @return a sequence of item paths to be transformed
*/
public fun selectItems(meta: Meta): Sequence<Name> =
meta.sequence().filter { matches(it.first, it.second) }.map { it.first }
meta.itemSequence().filter { matches(it.first, it.second) }.map { it.first }
/**
* Apply transformation for a single item (Node or Value) to the target
@ -37,10 +37,10 @@ public data class KeepTransformationRule(val selector: (Name) -> Boolean) :
}
override fun selectItems(meta: Meta): Sequence<Name> =
meta.sequence().map { it.first }.filter(selector)
meta.itemSequence().map { it.first }.filter(selector)
override fun <M : MutableMeta<M>> transformItem(name: Name, item: MetaItem<*>?, target: M) {
if (selector(name)) target.setItem(name, item)
if (selector(name)) target.set(name, item)
}
}
@ -170,7 +170,7 @@ public class MetaTransformationBuilder {
public fun keep(regex: String) {
transformations.add(
RegexItemTransformationRule(regex.toRegex()) { name, _, metaItem ->
setItem(name, metaItem)
set(name, metaItem)
})
}

View File

@ -30,7 +30,7 @@ class MetaBuilderTest {
"b.a[$it]" put it
}
}.seal()
assertEquals(10, meta.values().count())
assertEquals(10, meta.valueSequence().count())
val nodes = meta.getIndexed("b.a")

View File

@ -30,7 +30,7 @@ class MetaDelegateTest {
fun delegateTest() {
val testObject = TestScheme.empty()
testObject.setValue("myValue","theString".asValue())
testObject.set("myValue","theString".asValue())
testObject.enumValue = TestEnum.NO
testObject.inner = InnerSpec { innerValue = "ddd" }

View File

@ -17,9 +17,9 @@ class SchemeTest{
val meta = styled.toMeta()
assertEquals(10, meta.values().count())
assertEquals(10, meta.valueSequence().count())
val bNode = styled.getItem("b").node
val bNode = styled.get("b").node
val aNodes = bNode?.getIndexed("a")

View File

@ -4,15 +4,14 @@ import kotlin.test.Test
import kotlin.test.assertEquals
class SpecificationTest {
class TestStyled : Scheme() {
class TestStyled(config: Config, default: ItemProvider?) : Scheme(config, default) {
var list by numberList(1, 2, 3)
companion object : Specification<TestStyled> {
override fun read(meta: Meta, defaultProvider: ItemProvider): TestStyled =
TestStyled().apply {
this.config = meta.asConfig()
override fun read(items: ItemProvider): TestStyled = TestStyled(Config(), items)
}
override fun write(config: Config, defaultProvider: ItemProvider): TestStyled =
TestStyled(config, defaultProvider)
}
}