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 e5aa0c45..57364593 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt @@ -66,8 +66,14 @@ interface Meta : MetaRepr { /* 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 reture current [Meta] as a [NodeItem] + */ operator fun Meta?.get(name: Name): MetaItem<*>? { if (this == null) return null + if (name.isEmpty()) return NodeItem(this) return name.first()?.let { token -> val tail = name.cutFirst() when (tail.length) { @@ -78,6 +84,9 @@ operator fun Meta?.get(name: Name): MetaItem<*>? { } 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] + */ operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName()) /** @@ -113,12 +122,16 @@ operator fun Meta.iterator(): Iterator>> = sequence().ite /** * A meta node that ensures that all of its descendants has at least the same type */ -interface MetaNode> : Meta { +interface MetaNode> : Meta { override val items: Map> } -operator fun > MetaNode?.get(name: Name): MetaItem? { +/** + * The same as [Meta.get], but with specific node type + */ +operator fun > M?.get(name: Name): MetaItem? { if (this == null) return null + if (name.isEmpty()) return NodeItem(this) return name.first()?.let { token -> val tail = name.cutFirst() when (tail.length) { @@ -128,17 +141,9 @@ operator fun > MetaNode?.get(name: Name): MetaItem? { } } -operator fun > MetaNode?.get(key: String): MetaItem? = if (this == null) { - null -} else { - this[key.toName()] -} +operator fun > M?.get(key: String): MetaItem? = this[key.toName()] -operator fun > MetaNode?.get(key: NameToken): MetaItem? = if (this == null) { - null -} else { - this[key.asName()] -} +operator fun > M?.get(key: NameToken): MetaItem? = this[key.asName()] /** * Equals, hashcode and to string for any meta 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 4da08ce4..7a379f24 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt @@ -3,7 +3,7 @@ package hep.dataforge.meta import hep.dataforge.names.* import hep.dataforge.values.Value -interface MutableMeta> : MetaNode { +interface MutableMeta> : MetaNode { override val items: Map> operator fun set(name: Name, item: MetaItem<*>?) // fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit) @@ -54,13 +54,14 @@ abstract class AbstractMutableMeta> : AbstractMetaNode(), 0 -> error("Can't setValue meta item for empty name") 1 -> { val token = name.first()!! - replaceItem(token, get(name), wrapItem(item)) + @Suppress("UNCHECKED_CAST") val oldItem: MetaItem? = get(name) as? MetaItem + replaceItem(token, oldItem, wrapItem(item)) } else -> { val token = name.first()!! //get existing or create new node. Query is ignored for new node - if(items[token] == null){ - replaceItem(token,null, MetaItem.NodeItem(empty())) + if (items[token] == null) { + replaceItem(token, null, MetaItem.NodeItem(empty())) } items[token]?.node!![name.cutFirst()] = item } @@ -71,6 +72,7 @@ abstract class AbstractMutableMeta> : AbstractMetaNode(), @Suppress("NOTHING_TO_INLINE") inline fun MutableMeta<*>.remove(name: Name) = set(name, null) + @Suppress("NOTHING_TO_INLINE") inline fun MutableMeta<*>.remove(name: String) = remove(name.toName())