Fix MutableMetaView.kt

This commit is contained in:
Alexander Nozik 2025-01-18 13:48:24 +03:00
parent 27745802e1
commit 79bbc6c76b
3 changed files with 43 additions and 11 deletions
dataforge-meta/src
commonMain/kotlin/space/kscience/dataforge/meta
commonTest/kotlin/space/kscience/dataforge/meta

@ -2,14 +2,15 @@ package space.kscience.dataforge.meta
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.NameToken
import space.kscience.dataforge.names.parseAsName
import space.kscience.dataforge.names.plus
/**
* A [Meta] child proxy that creates required nodes on write
* A [Meta] child proxy that creates required nodes on value write
*/
public class MutableMetaView(
public val origin: MutableMeta,
public val path: Name
private class MutableMetaView(
val origin: MutableMeta,
val path: Name
) : MutableMeta {
override val items: Map<NameToken, MutableMeta>
@ -23,18 +24,24 @@ public class MutableMetaView(
override fun getOrCreate(name: Name): MutableMeta = MutableMetaView(origin, path + name)
override fun set(name: Name, node: Meta?) {
set(path + name, node)
if (origin[path + name] == null && node?.isEmpty() == true) return
origin[path + name] = node
}
override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta)
override fun hashCode(): Int = Meta.hashCode(this)
override fun hashCode(): Int = Meta.hashCode(this)
override fun toString(): String = Meta.toString(this)
}
public fun MutableMeta.view(name: Name): MutableMetaView = MutableMetaView(this, name)
/**
* Create a view of this [MutableMeta] node that creates child items only when their values are written.
*
* The difference between this method and regular [getOrCreate] is that [getOrCreate] always creates and attaches node
* even if it is empty.
*/
public fun MutableMeta.view(name: Name): MutableMeta = MutableMetaView(this, name)
public fun MutableMeta.view(name: String): MutableMeta = view(name.parseAsName())

@ -59,7 +59,7 @@ private class ObservableMetaWrapper(
fun removeNode(name: Name): Meta? {
val oldMeta = get(name)
//don't forget to remove listener
//remember to remove listener
oldMeta?.removeListener(this)
return oldMeta

@ -0,0 +1,25 @@
package space.kscience.dataforge.meta
import space.kscience.dataforge.names.asName
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class MutableMetaViewTest {
@Test
fun metaView() {
val meta = MutableMeta()
val view = meta.view("a".asName())
view["b"] = Meta.EMPTY
assertTrue { meta.items.isEmpty() }
view["c"] = Meta {
"d" put 22
}
assertEquals(22, meta["a.c.d"].int)
}
}