From 89f0d627b83856995bfc294d278da52303c8d01d Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 23 Dec 2020 19:09:02 +0300 Subject: [PATCH] A major refactor MutableItemProvider instead of Config --- build.gradle.kts | 2 +- .../kotlin/hep/dataforge/context/Context.kt | 6 +- .../dataforge/properties/ConfigProperty.kt | 3 +- .../hep/dataforge/io/BinaryMetaFormat.kt | 4 +- .../kotlin/hep/dataforge/io/EnvelopeParts.kt | 7 +- dataforge-meta/api/dataforge-meta.api | 150 ++++++++-------- .../kotlin/hep/dataforge/meta/ItemDelegate.kt | 2 +- .../kotlin/hep/dataforge/meta/ItemProvider.kt | 37 ++++ .../kotlin/hep/dataforge/meta/Meta.kt | 162 ++---------------- .../kotlin/hep/dataforge/meta/MetaItem.kt | 87 ++++++++++ .../hep/dataforge/meta/MetaWithDefault.kt | 2 +- .../hep/dataforge/meta/MutableItemDelegate.kt | 9 +- .../hep/dataforge/meta/MutableItemProvider.kt | 67 +++++--- .../kotlin/hep/dataforge/meta/MutableMeta.kt | 24 +-- .../kotlin/hep/dataforge/meta/Scheme.kt | 41 +++-- .../kotlin/hep/dataforge/meta/SealedMeta.kt | 23 +++ .../hep/dataforge/meta/Specification.kt | 51 ++---- .../meta/descriptors/ItemDescriptor.kt | 2 +- .../meta/descriptors/descriptorExtensions.kt | 18 ++ .../kotlin/hep/dataforge/meta/getIndexed.kt | 4 +- .../kotlin/hep/dataforge/meta/mapMeta.kt | 4 +- .../transformations/MetaTransformation.kt | 8 +- .../hep/dataforge/meta/MetaBuilderTest.kt | 2 +- .../hep/dataforge/meta/MetaDelegateTest.kt | 2 +- .../kotlin/hep/dataforge/meta/SchemeTest.kt | 4 +- .../hep/dataforge/meta/SpecificationTest.kt | 9 +- 26 files changed, 379 insertions(+), 351 deletions(-) create mode 100644 dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemProvider.kt create mode 100644 dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaItem.kt create mode 100644 dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/SealedMeta.kt create mode 100644 dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/descriptorExtensions.kt diff --git a/build.gradle.kts b/build.gradle.kts index e0c08431..c79a03bb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("ru.mipt.npm.project") } -val dataforgeVersion by extra("0.2.1-dev-5") +val dataforgeVersion by extra("0.2.1-dev-6") val bintrayRepo by extra("dataforge") val githubProject by extra("dataforge-core") diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Context.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Context.kt index 1646d45c..9ea626e9 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Context.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Context.kt @@ -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 { 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() } diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt index 329662b5..98a43b69 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt @@ -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( 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) { diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/BinaryMetaFormat.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/BinaryMetaFormat.kt index ab6f94bb..f09cdc04 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/BinaryMetaFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/BinaryMetaFormat.kt @@ -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) diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeParts.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeParts.kt index cae87229..45bfd988 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeParts.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeParts.kt @@ -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) { 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) } } diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index 5e88b4fa..ca03c72a 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -1,10 +1,4 @@ -public abstract class hep/dataforge/meta/AbstractMetaNode : hep/dataforge/meta/MetaBase, hep/dataforge/meta/MetaNode { - public fun ()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 ()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 ()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 ()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 ()V - public fun (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V - public synthetic fun (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun getConfig ()Lhep/dataforge/meta/Config; - public final fun getDefaultItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public fun (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public synthetic fun (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 (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 ()V public fun (Lhep/dataforge/meta/Config;)V public synthetic fun (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 (Lhep/dataforge/meta/Config;)V public synthetic fun (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; diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt index eab2573f..1c8c590b 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt @@ -11,7 +11,7 @@ import kotlin.properties.ReadOnlyProperty public typealias ItemDelegate = ReadOnlyProperty?> 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 diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemProvider.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemProvider.kt new file mode 100644 index 00000000..dd3194b6 --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemProvider.kt @@ -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] +} diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt index fb014593..44b05903 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt @@ -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() { - - abstract override fun equals(other: Any?): Boolean - - abstract override fun hashCode(): Int - - @Serializable(MetaItemSerializer::class) - public class ValueItem(public val value: Value) : MetaItem() { - 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(public val node: M) : MetaItem() { - //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.asMetaItem(): NodeItem = NodeItem(this) - /** * The object that could be represented as [Meta]. Meta provided by [toMeta] method should fully represent object state. * Meaning that two states with the same meta are equal. @@ -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> { +public fun Meta.valueSequence(): Sequence> { 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> { /** * Get a sequence of all [Name]-[MetaItem] pairs for all items including nodes */ -public fun Meta.sequence(): Sequence>> { - 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>> = 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>> = sequence().iterator() +public operator fun Meta.iterator(): Iterator>> = itemSequence().iterator() /** * A meta node that ensures that all of its descendants has at least the same type */ -public interface MetaNode> : Meta { +public interface TypedMeta> : Meta { override val items: Map> } /** * The same as [Meta.get], but with specific node type */ -public operator fun > M?.get(name: Name): MetaItem? = if (this == null) { +public operator fun > M?.get(name: Name): MetaItem? = if (this == null) { null } else { @Suppress("UNCHECKED_CAST", "ReplaceGetOrSet") (this as Meta).get(name) as MetaItem? // Do not change } -public operator fun > M?.get(key: String): MetaItem? = this[key.toName()] - -public operator fun > M?.get(key: NameToken): MetaItem? = this[key.asName()] +public operator fun > M?.get(key: String): MetaItem? = this[key.toName()] +public operator fun > M?.get(key: NameToken): MetaItem? = 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> : MetaNode, 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>, -) : AbstractMetaNode() - -/** - * 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 = 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 > MetaItem<*>?.enum(): E? = if (this is ValueItem && this.value is EnumValue<*>) { - this.value.value as E -} else { - string?.let { enumValueOf(it) } -} - -public val MetaItem<*>.stringList: List? get() = value?.list?.map { it.string } - -public val MetaItem?.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> : TypedMeta, MetaBase() public fun Meta.isEmpty(): Boolean = this === Meta.EMPTY || this.items.isEmpty() \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaItem.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaItem.kt new file mode 100644 index 00000000..899ca1f9 --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaItem.kt @@ -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() { + + abstract override fun equals(other: Any?): Boolean + + abstract override fun hashCode(): Int + + @Serializable(MetaItemSerializer::class) + public class ValueItem(public val value: Value) : MetaItem() { + 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(public val node: M) : MetaItem() { + //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.asMetaItem(): MetaItem.NodeItem = 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 > MetaItem<*>?.enum(): E? = if (this is MetaItem.ValueItem && this.value is EnumValue<*>) { + this.value.value as E +} else { + string?.let { enumValueOf(it) } +} + +public val MetaItem<*>.stringList: List? get() = value?.list?.map { it.string } + +public val MetaItem?.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 + } \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaWithDefault.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaWithDefault.kt index 2a225121..ebf20f13 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaWithDefault.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaWithDefault.kt @@ -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] } } diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemDelegate.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemDelegate.kt index 6e5cfc96..53f98997 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemDelegate.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemDelegate.kt @@ -13,12 +13,12 @@ public typealias MutableItemDelegate = ReadWriteProperty?> 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 > MutableItemProvider.enum( ): ReadWriteProperty = item(key).convert(MetaConverter.enum()) { default } +public fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty = item(key).convert( + reader = { it.node }, + writer = { it?.asMetaItem() } +) + public inline fun > M.node(key: Name? = null): ReadWriteProperty = item(key).convert(reader = { it?.let { it.node as M } }, writer = { it?.let { MetaItem.NodeItem(it) } }) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemProvider.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemProvider.kt index 6a43af6e..854bba62 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemProvider.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemProvider.kt @@ -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 = 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>, - 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, - 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): Unit = setIndexed(name, metas) -public operator fun MutableItemProvider.set(name: String, metas: Iterable): Unit = setIndexed(name.toName(), metas) +public operator fun MutableItemProvider.set(name: String, metas: Iterable): 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) + } diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt index 658f77cc..c0520792 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt @@ -2,7 +2,7 @@ package hep.dataforge.meta import hep.dataforge.names.* -public interface MutableMeta> : MetaNode, MutableItemProvider { +public interface MutableMeta> : TypedMeta, MutableItemProvider { override val items: Map> } @@ -11,7 +11,7 @@ public interface MutableMeta> : MetaNode, MutableItemP * * Changes in Meta are not thread safe. */ -public abstract class AbstractMutableMeta> : AbstractMetaNode(), MutableMeta { +public abstract class AbstractMutableMeta> : AbstractTypedMeta(), MutableMeta { protected val children: MutableMap> = LinkedHashMap() override val items: Map> @@ -50,7 +50,7 @@ public abstract class AbstractMutableMeta> : AbstractMetaNode 0 -> error("Can't setValue meta item for empty name") 1 -> { val token = name.firstOrNull()!! - @Suppress("UNCHECKED_CAST") val oldItem: MetaItem? = get(name) as? MetaItem + @Suppress("UNCHECKED_CAST") val oldItem: MetaItem? = getItem(name) as? MetaItem replaceItem(token, oldItem, wrapItem(item)) } else -> { @@ -59,28 +59,12 @@ public abstract class AbstractMutableMeta> : 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.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 */ diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt index 1fc74316..f2cb2bb7 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt @@ -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( 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( //} public fun Meta.asScheme(): Scheme = Scheme().apply { - config = this@asScheme.asConfig() + items = this@asScheme.asConfig() } public fun Meta.toScheme(spec: Specification, block: T.() -> Unit = {}): T = diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/SealedMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/SealedMeta.kt new file mode 100644 index 00000000..bcd69eaa --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/SealedMeta.kt @@ -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>, +) : AbstractTypedMeta() + +/** + * 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 = when (this) { + is MetaItem.ValueItem -> this + is MetaItem.NodeItem -> MetaItem.NodeItem(node.seal()) +} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt index 05c31dc3..3cf0c0b5 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt @@ -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 { /** * 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 { } /** - * Update given configuration using given type as a builder + * Update a [Config] using given specification */ -public fun Specification.update(meta: Meta, action: T.() -> Unit): T = - read(meta).apply(action) - - -/** - * Apply specified configuration to configurable - */ -public fun > T.configure(spec: S, action: C.() -> Unit): T = - apply { spec.update(toMeta(), action) } +public fun Config.update(spec: Specification, action: T.() -> Unit): T = + spec.write(this).apply(action) /** * Update configuration using given specification @@ -53,35 +44,23 @@ public fun > T.confi public fun > 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 > S.createStyle(action: C.() -> Unit): Meta = - Config().also { update(it, action) } - -public fun MetaItem<*>.spec(spec: Specification): T? = node?.let { - spec.wrap( - Config(), it - ) -} - -@JvmName("configSpec") -public fun MetaItem.spec(spec: Specification): T? = node?.let { spec.wrap(it) } +public fun MetaItem.withSpec(spec: Specification): T? = + node?.let { spec.write(it) } public fun MutableItemProvider.spec( - spec: Specification, key: Name? = null, + spec: Specification, + key: Name? = null, ): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Any?, property: KProperty<*>): T? { val name = key ?: property.name.asName() - return getItem(name).node?.let { spec.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 MutableItemProvider.spec( ): ReadWriteProperty = object : ReadWriteProperty { 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()) } } \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/ItemDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/ItemDescriptor.kt index ac1c4693..3fae4e20 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/ItemDescriptor.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/ItemDescriptor.kt @@ -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 diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/descriptorExtensions.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/descriptorExtensions.kt new file mode 100644 index 00000000..f05af69e --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/descriptorExtensions.kt @@ -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 > NodeDescriptor.enum( + key: Name, + default: E?, + crossinline modifier: ValueDescriptor.() -> Unit = {}, +): Unit = value(key) { + type(ValueType.STRING) + default?.let { + default(default) + } + allowedValues = enumValues().map { it.asValue() } + modifier() +} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt index 20ce93dc..6b01723a 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt @@ -29,8 +29,8 @@ public fun Meta.getIndexed(name: String): Map> = this@getIn * Get all items matching given name. */ @Suppress("UNCHECKED_CAST") -public fun > M.getIndexed(name: Name): Map> = +public fun > M.getIndexed(name: Name): Map> = (this as Meta).getIndexed(name) as Map> -public fun > M.getIndexed(name: String): Map> = +public fun > M.getIndexed(name: String): Map> = getIndexed(name.toName()) \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/mapMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/mapMeta.kt index 774a736a..6949987a 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/mapMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/mapMeta.kt @@ -35,12 +35,12 @@ public fun Map.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)) } } } \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt index 8e2c4d02..7048fe64 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt @@ -19,7 +19,7 @@ public interface TransformationRule { * @return a sequence of item paths to be transformed */ public fun selectItems(meta: Meta): Sequence = - 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 = - meta.sequence().map { it.first }.filter(selector) + meta.itemSequence().map { it.first }.filter(selector) override fun > 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) }) } diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaBuilderTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaBuilderTest.kt index 593401d1..ca5898e6 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaBuilderTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaBuilderTest.kt @@ -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") diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt index 6b8442d1..a6b514d4 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt @@ -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" } diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SchemeTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SchemeTest.kt index 1f7d7e97..14085f08 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SchemeTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SchemeTest.kt @@ -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") diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt index 587e2049..5bb93649 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt @@ -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 { - 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) } }