diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt index 8369080e..df19acd0 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt @@ -44,7 +44,7 @@ public fun DataNode.filter(filter: DataFilter): DataNode { /** * Filter data using [DataFilter] specification */ -public fun DataNode.filter(filter: Meta): DataNode = filter(DataFilter.wrap(filter)) +public fun DataNode.filter(filter: Meta): DataNode = filter(DataFilter.read(filter)) /** * Filter data using [DataFilter] builder 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 805a91b3..cae87229 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeParts.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeParts.kt @@ -88,7 +88,7 @@ public fun Envelope.parts(): EnvelopeParts { if (data == null) return emptyList() //TODO add zip folder reader val parts = meta.getIndexed(PARTS_KEY).values.mapNotNull { it.node }.map { - PartDescriptor.wrap(it) + PartDescriptor.read(it) } return if (parts.isEmpty()) { listOf(EnvelopePart(data!!, meta[MULTIPART_KEY].node)) diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api index 031cb33d..f4b8d3ed 100644 --- a/dataforge-meta/api/dataforge-meta.api +++ b/dataforge-meta/api/dataforge-meta.api @@ -493,10 +493,16 @@ public final class hep/dataforge/meta/SchemeKt { public class hep/dataforge/meta/SchemeSpec : hep/dataforge/meta/Specification, hep/dataforge/meta/descriptors/Described { public fun (Lkotlin/jvm/functions/Function0;)V public fun (Lkotlin/jvm/functions/Function3;)V + public synthetic fun empty ()Lhep/dataforge/meta/MutableItemProvider; + public fun empty ()Lhep/dataforge/meta/Scheme; public synthetic fun getDescriptor ()Lhep/dataforge/meta/descriptors/ItemDescriptor; public fun getDescriptor ()Lhep/dataforge/meta/descriptors/NodeDescriptor; - public synthetic fun wrap (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; - public fun wrap (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme; + public 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 final class hep/dataforge/meta/SealedMeta : hep/dataforge/meta/AbstractMetaNode { @@ -504,19 +510,24 @@ public final class hep/dataforge/meta/SealedMeta : hep/dataforge/meta/AbstractMe } public abstract interface class hep/dataforge/meta/Specification { - public abstract fun wrap (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; + 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 final class hep/dataforge/meta/Specification$DefaultImpls { - public static synthetic fun wrap$default (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lhep/dataforge/meta/MutableItemProvider; + public static fun 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 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 empty (Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider; - public static final fun invoke (Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; public static final fun spec (Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider; public static final fun spec (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Scheme;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; public static final fun spec (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; @@ -524,7 +535,6 @@ public final class hep/dataforge/meta/SpecificationKt { public static synthetic fun spec$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; public static final fun update (Lhep/dataforge/meta/Configurable;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; public static final fun update (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; - public static final fun wrap (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MutableItemProvider; } public abstract interface class hep/dataforge/meta/descriptors/Described { 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 b9e777e7..1fc74316 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt @@ -16,7 +16,10 @@ public open class Scheme( ) : Configurable, MutableItemProvider, Described, MetaRepr { override var config: Config = config - internal set + internal set(value) { + //Fix problem with `init` blocks in specifications + field = value.apply { update(field) } + } override var descriptor: NodeDescriptor? = descriptor internal set @@ -94,17 +97,18 @@ public open class SchemeSpec( } }) - /** - * If the provided [Meta] is a [Config] use it as a scheme base, otherwise use it as default. - */ - override fun wrap(meta: Meta, defaultProvider: ItemProvider): T = if (meta is Config) { - builder(meta, defaultProvider, descriptor) - } else { + override fun read(meta: Meta, defaultProvider: ItemProvider): T = builder(Config(), meta.withDefault(defaultProvider), descriptor) + + override fun wrap(config: Config, defaultProvider: ItemProvider): T { + return builder(config, defaultProvider, descriptor) } //TODO Generate descriptor from Scheme class override val descriptor: NodeDescriptor? get() = null + + @Suppress("OVERRIDE_BY_INLINE") + final override inline operator fun invoke(action: T.() -> Unit): T = empty().apply(action) } ///** @@ -118,7 +122,9 @@ public open class SchemeSpec( // override val defaultLayer: Meta get() = Laminate(meta, descriptor?.defaultItem().node) //} -public fun Meta.asScheme(): Scheme = Scheme(this.asConfig(), null, null) +public fun Meta.asScheme(): Scheme = Scheme().apply { + config = this@asScheme.asConfig() +} public fun Meta.toScheme(spec: Specification, block: T.() -> Unit = {}): T = - spec.wrap(this).apply(block) + spec.read(this).apply(block) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt index e4542933..05c31dc3 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt @@ -13,27 +13,33 @@ import kotlin.reflect.KProperty */ public interface Specification { /** - * Wrap generic configuration producing instance of desired type + * Read generic read-only meta with this [Specification] producing instance of desired type. */ - public fun wrap(meta: Meta, defaultProvider: ItemProvider = ItemProvider.EMPTY): T + public fun read(meta: Meta, defaultProvider: ItemProvider = ItemProvider.EMPTY): T + + /** + * Wrap mutable [Config], using it as inner storage (changes to [Specification] are reflected on [Config] + */ + public fun wrap(config: Config, defaultProvider: ItemProvider = ItemProvider.EMPTY): T = + read(config as Meta, defaultProvider) + + /** + * Generate an empty object + */ + public fun empty(): T = read(Meta.EMPTY) + + /** + * A convenience method to use specifications in builders + */ + public operator fun invoke(action: T.() -> Unit): T = empty().apply(action) } -public fun Specification.empty(): T = wrap(Config()) - -public inline operator fun Specification.invoke(action: T.() -> Unit): T = empty().apply(action) - /** * Update given configuration using given type as a builder */ -public fun Specification.update(meta: Meta, action: T.() -> Unit): T = wrap(meta).apply(action) +public fun Specification.update(meta: Meta, action: T.() -> Unit): T = + read(meta).apply(action) -/** - * Create a read-only version of - */ -public fun Specification.wrap(source: Meta): T { - val default = source.seal() - return wrap(source.asConfig(), default) -} /** * Apply specified configuration to configurable @@ -44,7 +50,10 @@ public fun > T.confi /** * Update configuration using given specification */ -public fun > Configurable.update(spec: S, action: C.() -> Unit): Configurable = +public fun > Configurable.update( + spec: S, + action: C.() -> Unit, +): Configurable = apply { spec.update(config, action) } /** @@ -63,11 +72,11 @@ public fun MetaItem<*>.spec(spec: Specification): T public fun MetaItem.spec(spec: Specification): T? = node?.let { spec.wrap(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.wrap(it) } + return getItem(name).node?.let { spec.read(it) } } override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { @@ -79,11 +88,11 @@ public fun MutableItemProvider.spec( public fun MutableItemProvider.spec( spec: Specification, default: T, - key: Name? = null + key: Name? = null, ): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Any?, property: KProperty<*>): T { val name = key ?: property.name.asName() - return getItem(name).node?.let { spec.wrap(it) } ?: default + return getItem(name).node?.let { spec.read(it) } ?: default } override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { 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 bf73ba8c..587e2049 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt @@ -4,13 +4,15 @@ import kotlin.test.Test import kotlin.test.assertEquals class SpecificationTest { - class TestStyled(config: Config, defaultProvider: ItemProvider) : - Scheme(config, defaultProvider) { + class TestStyled : Scheme() { var list by numberList(1, 2, 3) companion object : Specification { - override fun wrap(meta: Meta, defaultProvider: ItemProvider): TestStyled = - TestStyled(meta.asConfig(), defaultProvider) + override fun read(meta: Meta, defaultProvider: ItemProvider): TestStyled = + TestStyled().apply { + this.config = meta.asConfig() + + } } }