From 5632487dcaac66c5ad36d833352c6df0da94c674 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sat, 7 Aug 2021 10:31:32 +0300 Subject: [PATCH] tweak MetaDescriptor.kt --- .../kscience/dataforge/meta/MutableMeta.kt | 1 - .../kscience/dataforge/meta/ObservableMeta.kt | 2 +- .../meta/descriptors/MetaDescriptor.kt | 27 +++++++----- .../meta/descriptors/MetaDescriptorBuilder.kt | 43 +++++++++---------- 4 files changed, 37 insertions(+), 36 deletions(-) diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MutableMeta.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MutableMeta.kt index 6aaa5327..5b3265d9 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MutableMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/MutableMeta.kt @@ -149,7 +149,6 @@ public operator fun MutableMeta.set(name: Name, value: Value?): Unit = setValue( public fun MutableMeta.getOrCreate(key: String): MutableMeta = getOrCreate(Name.parse(key)) -@Serializable(MutableMetaSerializer::class) public interface MutableTypedMeta> : TypedMeta, MutableMeta { /** * Zero-copy attach or replace existing node. Node is used with any additional state, listeners, etc. diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableMeta.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableMeta.kt index 371d8e92..bfd8a862 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/ObservableMeta.kt @@ -71,7 +71,7 @@ private class ObservableMetaWrapper( origin.setMeta(name, node) // // if meta is observable propagate changes from it - if(node is ObservableMeta){ + if (node is ObservableMeta) { node.onChange(this) { changeName -> setMeta(name + changeName, node[changeName]) diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/MetaDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/MetaDescriptor.kt index 495b2cca..bad10e9a 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/MetaDescriptor.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/MetaDescriptor.kt @@ -9,23 +9,23 @@ import space.kscience.dataforge.values.Value import space.kscience.dataforge.values.ValueType /** - * The restriction on Meta node content + * Restrictions on value in the node */ -public enum class MetaNodeRequirements { +public enum class ValueRequirement { /** - * no restrictions + * No restrictions */ NONE, /** - * The node itself must exist + * The value is required */ - EXIST, + REQUIRED, /** - * Value must be present + * The value must be null */ - HAS_VALUE + ABSENT } /** @@ -45,7 +45,7 @@ public data class MetaDescriptor( public val info: String? = null, public val children: Map = emptyMap(), public val multiple: Boolean = false, - public val required: MetaNodeRequirements = MetaNodeRequirements.NONE, + public val valueRequirement: ValueRequirement = ValueRequirement.NONE, public val valueTypes: List? = null, public val indexKey: String = Meta.INDEX_KEY, public val defaultValue: Value? = null, @@ -56,6 +56,8 @@ public data class MetaDescriptor( } } +public val MetaDescriptor.required: Boolean get() = valueRequirement == ValueRequirement.REQUIRED || children.values.any { required } + public val MetaDescriptor.allowedValues: List? get() = attributes[MetaDescriptor.ALLOWED_VALUES_KEY]?.value?.list public operator fun MetaDescriptor.get(name: Name): MetaDescriptor? = when (name.length) { @@ -80,16 +82,19 @@ public val MetaDescriptor.defaultNode: Meta } public fun MetaDescriptor.validate(value: Value?): Boolean = if (value == null) { - required != MetaNodeRequirements.HAS_VALUE + valueRequirement != ValueRequirement.REQUIRED } else { - (valueTypes == null || value.type in valueTypes) && (allowedValues?.let { value in it } ?: true) + if (valueRequirement == ValueRequirement.ABSENT) false + else { + (valueTypes == null || value.type in valueTypes) && (allowedValues?.let { value in it } ?: true) + } } /** * Check if given item suits the descriptor */ public fun MetaDescriptor.validate(item: Meta?): Boolean { - if (item == null) return required == MetaNodeRequirements.NONE + if (item == null) return !required if (!validate(item.value)) return false children.forEach { (key, childDescriptor) -> diff --git a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder.kt b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder.kt index 7418c58c..4ac60c5c 100644 --- a/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder.kt +++ b/dataforge-meta/src/commonMain/kotlin/space/kscience/dataforge/meta/descriptors/MetaDescriptorBuilder.kt @@ -14,7 +14,7 @@ public class MetaDescriptorBuilder internal constructor() { public var info: String? = null public var children: MutableMap = hashMapOf() public var multiple: Boolean = false - public var required: MetaNodeRequirements = MetaNodeRequirements.NONE + public var valueRequirement: ValueRequirement = ValueRequirement.NONE public var type: List? = null @@ -35,15 +35,14 @@ public class MetaDescriptorBuilder internal constructor() { attributes.apply(block) } - public fun item(name: Name, descriptor: MetaDescriptor) { + public fun item(name: Name, descriptor: MetaDescriptor, block: MetaDescriptorBuilder.() -> Unit) { when (name.length) { - 0 -> {} - 1 -> { - children[name.first().body] = descriptor.toBuilder() - } - else -> { - children.getOrPut(name.first().body) { MetaDescriptorBuilder() }.item(name.cutFirst(), descriptor) + 0 -> { } + 1 -> children[name.first().body] = descriptor.toBuilder().apply(block) + else -> children.getOrPut(name.first().body) { + MetaDescriptorBuilder() + }.item(name.cutFirst(), descriptor, block) } } @@ -75,7 +74,7 @@ public class MetaDescriptorBuilder internal constructor() { info = info, children = children.mapValues { it.value.build() }, multiple = multiple, - required = required, + valueRequirement = valueRequirement, valueTypes = type, indexKey = indexKey, defaultValue = default, @@ -98,11 +97,9 @@ public fun MetaDescriptorBuilder.value( type: ValueType, vararg additionalTypes: ValueType, block: MetaDescriptorBuilder.() -> Unit -) { - item(name) { - type(type, *additionalTypes) - block() - } +): Unit = item(name) { + type(type, *additionalTypes) + block() } public fun MetaDescriptorBuilder.value( @@ -110,24 +107,24 @@ public fun MetaDescriptorBuilder.value( type: ValueType, vararg additionalTypes: ValueType, block: MetaDescriptorBuilder.() -> Unit -) { - value(Name.parse(name), type, additionalTypes = additionalTypes, block) -} +): Unit = value(Name.parse(name), type, additionalTypes = additionalTypes, block) /** * Create and configure child value descriptor */ -public fun MetaDescriptorBuilder.node(name: Name, block: MetaDescriptorBuilder.() -> Unit) { - item(name) { - type(ValueType.NULL) - block() - } +public fun MetaDescriptorBuilder.node(name: Name, block: MetaDescriptorBuilder.() -> Unit): Unit = item(name) { + valueRequirement = ValueRequirement.ABSENT + block() } public fun MetaDescriptorBuilder.node(name: String, block: MetaDescriptorBuilder.() -> Unit) { node(Name.parse(name), block) } +public fun MetaDescriptorBuilder.required() { + valueRequirement = ValueRequirement.REQUIRED +} + public inline fun > MetaDescriptorBuilder.enum( key: Name, default: E?, @@ -144,7 +141,7 @@ private fun MetaDescriptor.toBuilder(): MetaDescriptorBuilder = MetaDescriptorBu info = this@toBuilder.info children = this@toBuilder.children.mapValuesTo(LinkedHashMap()) { it.value.toBuilder() } multiple = this@toBuilder.multiple - required = this@toBuilder.required + valueRequirement = this@toBuilder.valueRequirement type = this@toBuilder.valueTypes indexKey = this@toBuilder.indexKey default = defaultValue