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 79145796..843e5acb 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/BinaryMetaFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/BinaryMetaFormat.kt @@ -90,6 +90,7 @@ object BinaryMetaFormat : MetaFormat { return readText(max = length) } + @Suppress("UNCHECKED_CAST") private fun Input.readMetaItem(): MetaItem { val keyChar = readByte().toChar() return when (keyChar) { @@ -119,6 +120,6 @@ object BinaryMetaFormat : MetaFormat { MetaItem.NodeItem(meta) } else -> error("Unknown serialization key character: $keyChar") - } + } as MetaItem } } \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/JsonMetaFormat.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/JsonMetaFormat.kt index 13cbc717..7815b69c 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/JsonMetaFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/JsonMetaFormat.kt @@ -49,8 +49,7 @@ fun Value.toJson(): JsonElement { fun Meta.toJson(): JsonObject { val map = this.items.mapValues { entry -> - val value = entry.value - when (value) { + when (val value = entry.value) { is MetaItem.ValueItem -> value.value.toJson() is MetaItem.NodeItem -> value.node.toJson() } @@ -70,8 +69,9 @@ class JsonMeta(val json: JsonObject) : Meta { } } + @Suppress("UNCHECKED_CAST") private operator fun MutableMap>.set(key: String, value: JsonElement) = when (value) { - is JsonPrimitive -> this[key] = MetaItem.ValueItem(value.toValue()) + is JsonPrimitive -> this[key] = MetaItem.ValueItem(value.toValue()) as MetaItem is JsonObject -> this[key] = MetaItem.NodeItem(value.toMeta()) is JsonArray -> { when { @@ -82,12 +82,12 @@ class JsonMeta(val json: JsonObject) : Meta { (it as JsonPrimitive).toValue() } ) - this[key] = MetaItem.ValueItem(listValue) + this[key] = MetaItem.ValueItem(listValue) as MetaItem } else -> value.forEachIndexed { index, jsonElement -> when (jsonElement) { is JsonObject -> this["$key[$index]"] = MetaItem.NodeItem(JsonMeta(jsonElement)) - is JsonPrimitive -> this["$key[$index]"] = MetaItem.ValueItem(jsonElement.toValue()) + is JsonPrimitive -> this["$key[$index]"] = MetaItem.ValueItem(jsonElement.toValue()) as MetaItem is JsonArray -> TODO("Nested arrays not supported") } } diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt index f6370942..3ea2a39e 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt @@ -1,6 +1,5 @@ package hep.dataforge.meta -import hep.dataforge.names.Name import hep.dataforge.names.NameToken import hep.dataforge.names.asName @@ -9,12 +8,12 @@ import hep.dataforge.names.asName /** * Mutable meta representing object state */ -open class Config : AbstractMutableMeta() { +class Config : AbstractMutableMeta() { /** * Attach configuration node instead of creating one */ - override fun wrap(name: Name, meta: Meta): Config = meta.toConfig() + override fun wrapNode(meta: Meta): Config = meta.toConfig() override fun empty(): Config = Config() @@ -29,7 +28,7 @@ fun Meta.toConfig(): Config = this as? Config ?: Config().also { builder -> this.items.mapValues { entry -> val item = entry.value builder[entry.key.asName()] = when (item) { - is MetaItem.ValueItem -> MetaItem.ValueItem(item.value) + is MetaItem.ValueItem -> item.value is MetaItem.NodeItem -> MetaItem.NodeItem(item.node.toConfig()) } } 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 329989de..4fb554ca 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt @@ -14,8 +14,8 @@ import hep.dataforge.values.boolean * * a [ValueItem] (leaf) * * a [NodeItem] (node) */ -sealed class MetaItem { - data class ValueItem(val value: Value) : MetaItem() +sealed class MetaItem { + data class ValueItem(val value: Value) : MetaItem() data class NodeItem(val node: M) : MetaItem() } @@ -35,7 +35,7 @@ interface MetaRepr { * * Same name siblings are supported via elements with the same [Name] but different queries */ interface Meta : MetaRepr { - val items: Map> + val items: Map> override fun toMeta(): Meta = this @@ -50,12 +50,7 @@ interface Meta : MetaRepr { /* Get operations*/ -/** - * Fast [String]-based accessor for item map - */ -operator fun Map.get(body: String, query: String = ""): T? = get(NameToken(body, query)) - -operator fun Meta?.get(name: Name): MetaItem? { +operator fun Meta?.get(name: Name): MetaItem<*>? { if (this == null) return null return name.first()?.let { token -> val tail = name.cutFirst() @@ -66,13 +61,13 @@ operator fun Meta?.get(name: Name): MetaItem? { } } -operator fun Meta?.get(token: NameToken): MetaItem? = this?.items?.get(token) -operator fun Meta?.get(key: String): MetaItem? = get(key.toName()) +operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token) +operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName()) /** * Get all items matching given name. */ -fun Meta.getAll(name: Name): Map> { +fun Meta.getAll(name: Name): Map> { val root = when (name.length) { 0 -> error("Can't use empty name for that") 1 -> this @@ -88,7 +83,7 @@ fun Meta.getAll(name: Name): Map> { ?: emptyMap() } -fun Meta.getAll(name: String): Map> = getAll(name.toName()) +fun Meta.getAll(name: String): Map> = getAll(name.toName()) /** * Get a sequence of [Name]-[Value] pairs @@ -109,8 +104,8 @@ 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)-> + if (item is NodeItem<*>) { + yieldAll(item.node.sequence().map { (innerKey, innerItem) -> (key + innerKey) to innerItem }) } @@ -130,7 +125,7 @@ interface MetaNode> : Meta { /** * Get all items matching given name. */ -fun > MetaNode.getAll(name: Name): Map> { +fun > M.getAll(name: Name): Map> { val root: MetaNode? = when (name.length) { 0 -> error("Can't use empty name for that") 1 -> this @@ -158,7 +153,11 @@ operator fun > MetaNode.get(name: Name): MetaItem? { } } -operator fun > MetaNode?.get(key: String): MetaItem? = this?.let { get(key.toName()) } +operator fun > MetaNode?.get(key: String): MetaItem? = if (this == null) { + null +} else { + this[key.toName()] +} /** * Equals and hash code implementation for meta node @@ -189,13 +188,14 @@ class SealedMeta internal constructor(override val items: Map entry.value.seal() }) +@Suppress("UNCHECKED_CAST") fun MetaItem<*>.seal(): MetaItem = when (this) { - is MetaItem.ValueItem -> MetaItem.ValueItem(value) - is MetaItem.NodeItem -> MetaItem.NodeItem(node.seal()) + is ValueItem -> this as MetaItem + is NodeItem -> NodeItem(node.seal()) } object EmptyMeta : Meta { - override val items: Map> = emptyMap() + override val items: Map> = emptyMap() } /** @@ -203,8 +203,8 @@ object EmptyMeta : Meta { */ val MetaItem<*>?.value - get() = (this as? MetaItem.ValueItem)?.value - ?: (this?.node?.get(VALUE_KEY) as? MetaItem.ValueItem)?.value + get() = (this as? ValueItem)?.value + ?: (this?.node?.get(VALUE_KEY) as? ValueItem)?.value val MetaItem<*>?.string get() = value?.string val MetaItem<*>?.boolean get() = value?.boolean @@ -226,8 +226,8 @@ val MetaItem<*>?.stringList get() = value?.list?.map { it.string } ?: emptyList( val MetaItem?.node: M? get() = when (this) { null -> null - is MetaItem.ValueItem -> error("Trying to interpret value meta item as node item") - is MetaItem.NodeItem -> node + is ValueItem -> error("Trying to interpret value meta item as node item") + is NodeItem -> node } /** @@ -239,4 +239,4 @@ interface Metoid { fun Value.toMeta() = buildMeta { Meta.VALUE_KEY to this } -fun Meta.isEmpty() = this === EmptyMeta || this.items.isEmpty() \ No newline at end of file +fun Meta.isEmpty() = this === EmptyMeta || this.items.isEmpty() diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt index c8911c60..0b5c83d6 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt @@ -1,6 +1,5 @@ package hep.dataforge.meta -import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.values.Value @@ -8,7 +7,7 @@ import hep.dataforge.values.Value * DSL builder for meta. Is not intended to store mutable state */ class MetaBuilder : AbstractMutableMeta() { - override fun wrap(name: Name, meta: Meta): MetaBuilder = meta.builder() + override fun wrapNode(meta: Meta): MetaBuilder = meta.builder() override fun empty(): MetaBuilder = MetaBuilder() infix fun String.to(value: Any) { @@ -39,7 +38,7 @@ fun Meta.builder(): MetaBuilder { items.mapValues { entry -> val item = entry.value builder[entry.key.asName()] = when (item) { - is MetaItem.ValueItem -> MetaItem.ValueItem(item.value) + is MetaItem.ValueItem -> item.value is MetaItem.NodeItem -> MetaItem.NodeItem(item.node.builder()) } } diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaTransformation.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaTransformation.kt index ab1a95fa..11ef9cdb 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaTransformation.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaTransformation.kt @@ -80,6 +80,9 @@ data class RegexpItemTransformationRule( } +/** + * A set of [TransformationRule] to either transform static meta or create dynamically updated [MutableMeta] + */ inline class MetaTransformation(val transformations: Collection) { /** @@ -109,7 +112,7 @@ inline class MetaTransformation(val transformations: Collection> bind(source: MutableMeta<*>, target: M) { - source.onChange(target) { name, oldItem, newItem -> + source.onChange(target) { name, _, newItem -> transformations.forEach { t -> if (t.matches(name, newItem)) { t.transformItem(name, newItem, target) @@ -123,18 +126,29 @@ inline class MetaTransformation(val transformations: Collection() + /** + * Keep all items with name satisfying the criteria + */ fun keep(selector: (Name) -> Boolean) { transformations.add(KeepTransformationRule(selector)) } + /** + * Keep specific item (including its descendants) + */ fun keep(name: Name) { keep{it == name} } - fun keepNode(name: Name){ - keep{it.startsWith(name)} + fun move(from: Name, to: Name){ + transformations.add( + SingleItemTransformationRule(from){ _, item -> setItem(to, item)} + ) } } \ No newline at end of file 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 83edc56b..aebb18d6 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt @@ -10,15 +10,8 @@ internal data class MetaListener( interface MutableMeta> : MetaNode { - /** - * Transform given meta to node type of this meta tree - * @param name the name of the node where meta should be attached. Needed for correct assignment validators and styles - * @param meta the node itself - */ - fun wrap(name: Name, meta: Meta): M - override val items: Map> - operator fun set(name: Name, item: MetaItem?) + operator fun set(name: Name, item: MetaItem<*>?) fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit) fun removeListener(owner: Any? = null) } @@ -69,59 +62,70 @@ abstract class AbstractMutableMeta> : AbstractMetaNode(), itemChanged(key.asName(), oldItem, newItem) } + @Suppress("UNCHECKED_CAST") + protected fun wrapItem(item: MetaItem<*>?): MetaItem? = when (item) { + null -> null + is MetaItem.ValueItem -> item as MetaItem + is MetaItem.NodeItem<*> -> MetaItem.NodeItem(wrapNode(item.node)) + } + + /** + * Transform given meta to node type of this meta tree + */ + protected abstract fun wrapNode(meta: Meta): M + /** * Create empty node */ internal abstract fun empty(): M - override operator fun set(name: Name, item: MetaItem?) { + override operator fun set(name: Name, item: MetaItem<*>?) { when (name.length) { 0 -> error("Can't setValue meta item for empty name") 1 -> { val token = name.first()!! - replaceItem(token, get(name), item) + replaceItem(token, get(name), wrapItem(item)) } else -> { val token = name.first()!! //get existing or create new node. Query is ignored for new node - val child = this.items[token]?.node - ?: empty().also { this[token.body.toName()] = MetaItem.NodeItem(it) } - child[name.cutFirst()] = item + if(items[token] == null){ + replaceItem(token,null, MetaItem.NodeItem(empty())) + } + items[token]?.node!![name.cutFirst()] = item } } } } -fun > MutableMeta.remove(name: Name) = set(name, null) -fun > MutableMeta.remove(name: String) = remove(name.toName()) +fun MutableMeta<*>.remove(name: Name) = set(name, null) +fun MutableMeta<*>.remove(name: String) = remove(name.toName()) -fun > MutableMeta.setValue(name: Name, value: Value) = +fun MutableMeta<*>.setValue(name: Name, value: Value) = set(name, MetaItem.ValueItem(value)) -fun > MutableMeta.setValue(name: String, value: Value) = +fun MutableMeta<*>.setValue(name: String, value: Value) = set(name.toName(), MetaItem.ValueItem(value)) -//fun > MutableMeta.setItem(token: NameToken, item: MetaItem?) = set(token.asName(), item) -//fun > MutableMeta.setItem(name: String, item: MetaItem) = set(name.toName(), item) - -fun > MutableMeta.setItem(name: Name, item: MetaItem<*>) { +fun MutableMeta<*>.setItem(name: Name, item: MetaItem<*>?) { when (item) { - is MetaItem.ValueItem<*> -> setValue(name, item.value) + null -> remove(name) + is MetaItem.ValueItem -> setValue(name, item.value) is MetaItem.NodeItem<*> -> setNode(name, item.node) } } -fun > MutableMeta.setItem(name: String, item: MetaItem<*>) = setItem(name.toName(), item) +fun MutableMeta<*>.setItem(name: String, item: MetaItem<*>?) = setItem(name.toName(), item) -fun > MutableMeta.setNode(name: Name, node: Meta) = - set(name, MetaItem.NodeItem(wrap(name, node))) +fun MutableMeta<*>.setNode(name: Name, node: Meta) = + set(name, MetaItem.NodeItem(node)) -fun > MutableMeta.setNode(name: String, node: Meta) = setNode(name.toName(), node) +fun MutableMeta<*>.setNode(name: String, node: Meta) = setNode(name.toName(), node) /** * Universal set method */ -operator fun > MutableMeta.set(name: Name, value: Any?) { +operator fun MutableMeta<*>.set(name: Name, value: Any?) { when (value) { null -> remove(name) is MetaItem<*> -> setItem(name, value) @@ -131,9 +135,9 @@ operator fun > MutableMeta.set(name: Name, value: Any?) { } } -operator fun > M.set(name: NameToken, value: Any?) = set(name.asName(), value) +operator fun MutableMeta<*>.set(name: NameToken, value: Any?) = set(name.asName(), value) -operator fun > M.set(key: String, value: Any?) = set(key.toName(), value) +operator fun MutableMeta<*>.set(key: String, value: Any?) = set(key.toName(), value) /** * Update existing mutable node with another node. The rules are following: @@ -143,8 +147,7 @@ operator fun > M.set(key: String, value: Any?) = set(key.toNa */ fun > M.update(meta: Meta) { meta.items.forEach { entry -> - val value = entry.value - when (value) { + 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) } @@ -154,10 +157,10 @@ fun > M.update(meta: Meta) { /* Same name siblings generation */ -fun > M.setIndexedItems( +fun MutableMeta<*>.setIndexedItems( name: Name, - items: Iterable>, - indexFactory: MetaItem.(index: Int) -> String = { it.toString() } + items: Iterable>, + indexFactory: MetaItem<*>.(index: Int) -> String = { it.toString() } ) { val tokens = name.tokens.toMutableList() val last = tokens.last() @@ -168,21 +171,21 @@ fun > M.setIndexedItems( } } -fun > M.setIndexed( +fun MutableMeta<*>.setIndexed( name: Name, metas: Iterable, - indexFactory: MetaItem.(index: Int) -> String = { it.toString() } + indexFactory: MetaItem<*>.(index: Int) -> String = { it.toString() } ) { - setIndexedItems(name, metas.map { MetaItem.NodeItem(wrap(name, it)) }, indexFactory) + setIndexedItems(name, metas.map { MetaItem.NodeItem(it) }, indexFactory) } -operator fun > M.set(name: Name, metas: Iterable) = setIndexed(name, metas) -operator fun > M.set(name: String, metas: Iterable) = setIndexed(name.toName(), metas) +operator fun MutableMeta<*>.set(name: Name, metas: Iterable): Unit = setIndexed(name, metas) +operator fun MutableMeta<*>.set(name: String, metas: Iterable): Unit = setIndexed(name.toName(), metas) /** * Append the node with a same-name-sibling, automatically generating numerical index */ -fun > M.append(name: Name, value: Any?) { +fun MutableMeta<*>.append(name: Name, value: Any?) { require(!name.isEmpty()) { "Name could not be empty for append operation" } val newIndex = name.last()!!.index if (newIndex.isNotEmpty()) { @@ -193,4 +196,4 @@ fun > M.append(name: Name, value: Any?) { } } -fun > M.append(name: String, value: Any?) = append(name.toName(), value) \ No newline at end of file +fun MutableMeta<*>.append(name: String, value: Any?) = append(name.toName(), value) \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Styled.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Styled.kt index 136c5617..39b47227 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Styled.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Styled.kt @@ -12,14 +12,11 @@ import kotlin.reflect.KProperty * @param style - the style */ class Styled(val base: Meta, val style: Config = Config().empty()) : AbstractMutableMeta() { - override fun wrap(name: Name, meta: Meta): Styled { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } + override fun wrapNode(meta: Meta): Styled = Styled(meta) - override fun empty(): Styled { - TODO("not implemented") //To change body of created functions use File | Settings | File Templates. - } + override fun empty(): Styled = Styled(EmptyMeta) + @Suppress("UNCHECKED_CAST") override val items: Map> get() = (base.items.keys + style.items.keys).associate { key -> val value = base.items[key] @@ -27,10 +24,10 @@ class Styled(val base: Meta, val style: Config = Config().empty()) : AbstractMut val item: MetaItem = when (value) { null -> when (styleValue) { null -> error("Should be unreachable") - is MetaItem.ValueItem -> MetaItem.ValueItem(styleValue.value) is MetaItem.NodeItem -> MetaItem.NodeItem(Styled(style.empty(), styleValue.node)) + else -> styleValue.value as MetaItem } - is MetaItem.ValueItem -> MetaItem.ValueItem(value.value) + is MetaItem.ValueItem -> value as MetaItem is MetaItem.NodeItem -> MetaItem.NodeItem( Styled(value.node, styleValue?.node ?: Config.empty()) ) @@ -38,7 +35,7 @@ class Styled(val base: Meta, val style: Config = Config().empty()) : AbstractMut key to item } - override fun set(name: Name, item: MetaItem?) { + override fun set(name: Name, item: MetaItem<*>?) { if (item == null) { style.remove(name) } else { diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt index b0aa8a7d..504c07d2 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt @@ -121,6 +121,11 @@ fun Name.withIndex(index: String): Name { return Name(tokens) } +/** + * Fast [String]-based accessor for item map + */ +operator fun Map.get(body: String, query: String = ""): T? = get(NameToken(body, query)) + operator fun Map.get(name: String) = get(name.toName()) operator fun MutableMap.set(name: String, value: T) = set(name.toName(), value) diff --git a/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt b/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt index 4719831b..12b8db9e 100644 --- a/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt +++ b/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt @@ -35,12 +35,13 @@ class DynamicMeta(val obj: dynamic) : Meta { private fun isArray(@Suppress("UNUSED_PARAMETER") obj: dynamic): Boolean = js("Array.isArray(obj)") as Boolean + @Suppress("UNCHECKED_CAST") private fun asItem(obj: dynamic): MetaItem? { - if (obj == null) return MetaItem.ValueItem(Null) - return when (jsTypeOf(obj)) { - "boolean" -> MetaItem.ValueItem(Value.of(obj as Boolean)) - "number" -> MetaItem.ValueItem(Value.of(obj as Number)) - "string" -> MetaItem.ValueItem(Value.of(obj as String)) + if (obj == null) return MetaItem.ValueItem(Null) as MetaItem + return when (jsTypeOf(obj as? Any)) { + "boolean" -> MetaItem.ValueItem(Value.of(obj as Boolean)) as MetaItem + "number" -> MetaItem.ValueItem(Value.of(obj as Number)) as MetaItem + "string" -> MetaItem.ValueItem(Value.of(obj as String)) as MetaItem "object" -> MetaItem.NodeItem(DynamicMeta(obj)) else -> null } diff --git a/dataforge-workspace/src/jvmTest/kotlin/hep/dataforge/workspace/SimpleWorkspaceTest.kt b/dataforge-workspace/src/jvmTest/kotlin/hep/dataforge/workspace/SimpleWorkspaceTest.kt index 962dab53..d47f972f 100644 --- a/dataforge-workspace/src/jvmTest/kotlin/hep/dataforge/workspace/SimpleWorkspaceTest.kt +++ b/dataforge-workspace/src/jvmTest/kotlin/hep/dataforge/workspace/SimpleWorkspaceTest.kt @@ -61,13 +61,13 @@ class SimpleWorkspaceTest { allData() } joinByGroup { context -> - group("even", filter = { name, data -> name.toString().toInt() % 2 == 0 }) { + group("even", filter = { name, _ -> name.toString().toInt() % 2 == 0 }) { result { data -> context.logger.info { "Starting even" } data.values.average() } } - group("odd", filter = { name, data -> name.toString().toInt() % 2 == 1 }) { + group("odd", filter = { name, _ -> name.toString().toInt() % 2 == 1 }) { result { data -> context.logger.info { "Starting odd" } data.values.average()