diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/NodeDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/NodeDescriptor.kt
index 2d7fa6be..bf09cf70 100644
--- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/NodeDescriptor.kt
+++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/NodeDescriptor.kt
@@ -22,6 +22,7 @@
package hep.dataforge.descriptors
import hep.dataforge.meta.*
+import hep.dataforge.names.NameToken
import hep.dataforge.names.toName
/**
@@ -39,6 +40,14 @@ class NodeDescriptor(override val config: Config) : Specification {
*/
var name: String by string { error("Anonymous descriptors are not allowed") }
+
+ /**
+ * The default for this node. Null if there is no default.
+ *
+ * @return
+ */
+ var default: Meta? by node()
+
/**
* True if multiple children with this nodes name are allowed. Anonymous
* nodes are always single
@@ -52,7 +61,7 @@ class NodeDescriptor(override val config: Config) : Specification {
*
* @return
*/
- var required: Boolean by boolean(false)
+ var required: Boolean by boolean { default == null }
/**
* The node description
@@ -78,6 +87,18 @@ class NodeDescriptor(override val config: Config) : Specification {
name to ValueDescriptor.wrap(node.node ?: error("Value descriptor must be a node"))
}
+ fun value(name: String, descriptor: ValueDescriptor) {
+ val token = NameToken("value", name)
+ config[token] = descriptor.config
+ }
+
+ /**
+ * Add a value descriptor using block for
+ */
+ fun value(name: String, block: ValueDescriptor.() -> Unit) {
+ value(name, ValueDescriptor.build { this.name = name }.apply(block))
+ }
+
/**
* The map of children node descriptors
*/
@@ -87,43 +108,15 @@ class NodeDescriptor(override val config: Config) : Specification {
}
- /**
- * Check if this node has default
- *
- * @return
- */
- fun hasDefault(): Boolean {
- return meta.hasMeta("default")
+ fun node(name: String, descriptor: NodeDescriptor) {
+ val token = NameToken("node", name)
+ config[token] = descriptor.config
}
- /**
- * The default meta for this node (could be multiple). Null if not defined
- *
- * @return
- */
- val default: List by nodeList(def = emptyList())
-
- /**
- * Identify if this descriptor has child value descriptor with default
- *
- * @param name
- * @return
- */
- fun hasDefaultForValue(name: String): Boolean {
- return getValueDescriptor(name)?.hasDefault() ?: false
+ fun node(name: String, block: NodeDescriptor.() -> Unit) {
+ node(name, NodeDescriptor.build { this.name = name }.apply(block))
}
- /**
- * The key of the value which is used to display this node in case it is
- * multiple. By default, the key is empty which means that node index is
- * used.
- *
- * @return
- */
- val key: String by stringValue(def = "")
-
-
- fun builder(): DescriptorBuilder = DescriptorBuilder(this.name, Configuration(this.meta))
//override val descriptor: NodeDescriptor = empty("descriptor")
@@ -131,8 +124,5 @@ class NodeDescriptor(override val config: Config) : Specification {
override fun wrap(config: Config): NodeDescriptor = NodeDescriptor(config)
- fun empty(nodeName: String): NodeDescriptor {
- return NodeDescriptor(Meta.buildEmpty(nodeName))
- }
}
}
diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/ValueDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/ValueDescriptor.kt
index 3416b55b..7f066e99 100644
--- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/ValueDescriptor.kt
+++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/ValueDescriptor.kt
@@ -17,7 +17,10 @@
package hep.dataforge.descriptors
import hep.dataforge.meta.*
-import hep.dataforge.values.*
+import hep.dataforge.values.False
+import hep.dataforge.values.True
+import hep.dataforge.values.Value
+import hep.dataforge.values.ValueType
/**
* A descriptor for meta value
@@ -35,6 +38,10 @@ class ValueDescriptor(override val config: Config) : Specification {
*/
var default: Value? by value()
+ fun default(v: Any) {
+ this.default = Value.of(v)
+ }
+
/**
* True if multiple values with this name are allowed.
*
@@ -72,6 +79,10 @@ class ValueDescriptor(override val config: Config) : Specification {
it?.list?.map { v -> ValueType.valueOf(v.string) } ?: emptyList()
}
+ fun type(vararg t: ValueType) {
+ this.type = listOf(*t)
+ }
+
var tags: List by value().map { value ->
value?.list?.map { it.string } ?: emptyList()
}
@@ -103,10 +114,24 @@ class ValueDescriptor(override val config: Config) : Specification {
}
}
+ /**
+ * Allow given list of value and forbid others
+ */
+ fun allow(vararg v: Any) {
+ this.allowedValues = v.map { Value.of(it) }
+ }
+
companion object : SpecificationCompanion {
override fun wrap(config: Config): ValueDescriptor = ValueDescriptor(config)
+ inline fun > enum(name: String) =
+ ValueDescriptor.build {
+ this.name = name
+ type(ValueType.STRING)
+ this.allowedValues = enumValues().map { Value.of(it.name) }
+ }
+
// /**
// * Build a value descriptor from annotation
// */
diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/annotations.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/annotations.kt
index 25349ea7..d65a0e79 100644
--- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/annotations.kt
+++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/descriptors/annotations.kt
@@ -23,14 +23,14 @@ import kotlin.reflect.KClass
@MustBeDocumented
annotation class ValueDef(
val key: String,
- val type: Array = [ValueType.STRING],
+ val type: Array = arrayOf(ValueType.STRING),
val multiple: Boolean = false,
val def: String = "",
val info: String = "",
val required: Boolean = true,
- val allowed: Array = [],
+ val allowed: Array = emptyArray(),
val enumeration: KClass<*> = Any::class,
- val tags: Array = []
+ val tags: Array = emptyArray()
)
@MustBeDocumented
@@ -39,11 +39,11 @@ annotation class NodeDef(
val info: String = "",
val multiple: Boolean = false,
val required: Boolean = false,
- val tags: Array = [],
+ val tags: Array = emptyArray(),
/**
* A list of child value descriptors
*/
- val values: Array = [],
+ val values: Array = emptyArray(),
/**
* A target class for this node to describe
* @return
@@ -135,11 +135,11 @@ annotation class DescriptorValue(val def: ValueDef)
@MustBeDocumented
annotation class ValueProperty(
val name: String = "",
- val type: Array = [ValueType.STRING],
+ val type: Array = arrayOf(ValueType.STRING),
val multiple: Boolean = false,
val def: String = "",
val enumeration: KClass<*> = Any::class,
- val tags: Array = []
+ val tags: Array = emptyArray()
)
diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ConfigDelegates.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ConfigDelegates.kt
index 8e717948..9a5f15cb 100644
--- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ConfigDelegates.kt
+++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ConfigDelegates.kt
@@ -11,45 +11,45 @@ import kotlin.jvm.JvmName
* A property delegate that uses custom key
*/
fun Configurable.value(default: Any = Null, key: String? = null) =
- ValueConfigDelegate(config, key, Value.of(default))
+ MutableValueDelegate(config, key, Value.of(default))
fun Configurable.string(default: String? = null, key: String? = null) =
- StringConfigDelegate(config, key, default)
+ MutableStringDelegate(config, key, default)
fun Configurable.boolean(default: Boolean? = null, key: String? = null) =
- BooleanConfigDelegate(config, key, default)
+ MutableBooleanDelegate(config, key, default)
fun Configurable.number(default: Number? = null, key: String? = null) =
- NumberConfigDelegate(config, key, default)
+ MutableNumberDelegate(config, key, default)
-fun Configurable.child(key: String? = null) = MetaNodeDelegate(config, key)
+fun Configurable.node(key: String? = null) = MutableNodeDelegate(config, key)
//fun Configurable.spec(spec: Specification, key: String? = null) = ChildConfigDelegate(key) { spec.wrap(this) }
@JvmName("safeString")
fun Configurable.string(default: String, key: String? = null) =
- SafeStringConfigDelegate(config, key) { default }
+ MutableSafeStringDelegate(config, key) { default }
@JvmName("safeBoolean")
fun Configurable.boolean(default: Boolean, key: String? = null) =
- SafeBooleanConfigDelegate(config, key) { default }
+ MutableSafeBooleanDelegate(config, key) { default }
@JvmName("safeNumber")
fun Configurable.number(default: Number, key: String? = null) =
- SafeNumberConfigDelegate(config, key) { default }
+ MutableSafeNumberDelegate(config, key) { default }
@JvmName("safeString")
fun Configurable.string(key: String? = null, default: () -> String) =
- SafeStringConfigDelegate(config, key, default)
+ MutableSafeStringDelegate(config, key, default)
@JvmName("safeBoolean")
fun Configurable.boolean(key: String? = null, default: () -> Boolean) =
- SafeBooleanConfigDelegate(config, key, default)
+ MutableSafeBooleanDelegate(config, key, default)
@JvmName("safeNumber")
fun Configurable.number(key: String? = null, default: () -> Number) =
- SafeNumberConfigDelegate(config, key, default)
+ MutableSafeNumberDelegate(config, key, default)
inline fun > Configurable.enum(default: E, key: String? = null) =
- SafeEnumvConfigDelegate(config, key, default) { enumValueOf(it) }
\ No newline at end of file
+ MutableSafeEnumvDelegate(config, key, default) { enumValueOf(it) }
\ No newline at end of file
diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Delegates.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Delegates.kt
index 5a7e845d..119b78b0 100644
--- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Delegates.kt
+++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Delegates.kt
@@ -164,23 +164,23 @@ inline fun > Meta.enum(default: E, key: String? = null) =
SafeEnumDelegate(this, key, default) { enumValueOf(it) }
-/* Config delegates */
+/* Read-write delegates */
-class ValueConfigDelegate>(
- val config: M,
+class MutableValueDelegate>(
+ val meta: M,
private val key: String? = null,
private val default: Value? = null
) : ReadWriteProperty {
override fun getValue(thisRef: Any?, property: KProperty<*>): Value? {
- return config[key ?: property.name]?.value ?: default
+ return meta[key ?: property.name]?.value ?: default
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Value?) {
val name = key ?: property.name
if (value == null) {
- config.remove(name)
+ meta.remove(name)
} else {
- config.setValue(name, value)
+ meta.setValue(name, value)
}
}
@@ -188,59 +188,59 @@ class ValueConfigDelegate>(
ReadWriteDelegateWrapper(this, reader, writer)
}
-class StringConfigDelegate>(
- val config: M,
+class MutableStringDelegate>(
+ val meta: M,
private val key: String? = null,
private val default: String? = null
) : ReadWriteProperty {
override fun getValue(thisRef: Any?, property: KProperty<*>): String? {
- return config[key ?: property.name]?.string ?: default
+ return meta[key ?: property.name]?.string ?: default
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String?) {
val name = key ?: property.name
if (value == null) {
- config.remove(name)
+ meta.remove(name)
} else {
- config.setValue(name, value.asValue())
+ meta.setValue(name, value.asValue())
}
}
}
-class BooleanConfigDelegate>(
- val config: M,
+class MutableBooleanDelegate>(
+ val meta: M,
private val key: String? = null,
private val default: Boolean? = null
) : ReadWriteProperty {
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean? {
- return config[key ?: property.name]?.boolean ?: default
+ return meta[key ?: property.name]?.boolean ?: default
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean?) {
val name = key ?: property.name
if (value == null) {
- config.remove(name)
+ meta.remove(name)
} else {
- config.setValue(name, value.asValue())
+ meta.setValue(name, value.asValue())
}
}
}
-class NumberConfigDelegate>(
- val config: M,
+class MutableNumberDelegate>(
+ val meta: M,
private val key: String? = null,
private val default: Number? = null
) : ReadWriteProperty {
override fun getValue(thisRef: Any?, property: KProperty<*>): Number? {
- return config[key ?: property.name]?.number ?: default
+ return meta[key ?: property.name]?.number ?: default
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Number?) {
val name = key ?: property.name
if (value == null) {
- config.remove(name)
+ meta.remove(name)
} else {
- config.setValue(name, value.asValue())
+ meta.setValue(name, value.asValue())
}
}
@@ -252,8 +252,8 @@ class NumberConfigDelegate>(
//Delegates with non-null values
-class SafeStringConfigDelegate>(
- val config: M,
+class MutableSafeStringDelegate>(
+ val meta: M,
private val key: String? = null,
default: () -> String
) : ReadWriteProperty {
@@ -261,16 +261,16 @@ class SafeStringConfigDelegate>(
private val default: String by lazy(default)
override fun getValue(thisRef: Any?, property: KProperty<*>): String {
- return config[key ?: property.name]?.string ?: default
+ return meta[key ?: property.name]?.string ?: default
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
- config.setValue(key ?: property.name, value.asValue())
+ meta.setValue(key ?: property.name, value.asValue())
}
}
-class SafeBooleanConfigDelegate>(
- val config: M,
+class MutableSafeBooleanDelegate>(
+ val meta: M,
private val key: String? = null,
default: () -> Boolean
) : ReadWriteProperty {
@@ -278,16 +278,16 @@ class SafeBooleanConfigDelegate>(
private val default: Boolean by lazy(default)
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
- return config[key ?: property.name]?.boolean ?: default
+ return meta[key ?: property.name]?.boolean ?: default
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
- config.setValue(key ?: property.name, value.asValue())
+ meta.setValue(key ?: property.name, value.asValue())
}
}
-class SafeNumberConfigDelegate>(
- val config: M,
+class MutableSafeNumberDelegate>(
+ val meta: M,
private val key: String? = null,
default: () -> Number
) : ReadWriteProperty {
@@ -295,11 +295,11 @@ class SafeNumberConfigDelegate>(
private val default: Number by lazy(default)
override fun getValue(thisRef: Any?, property: KProperty<*>): Number {
- return config[key ?: property.name]?.number ?: default
+ return meta[key ?: property.name]?.number ?: default
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Number) {
- config.setValue(key ?: property.name, value.asValue())
+ meta.setValue(key ?: property.name, value.asValue())
}
val double get() = ReadWriteDelegateWrapper(this, reader = { it.toDouble() }, writer = { it })
@@ -308,48 +308,48 @@ class SafeNumberConfigDelegate>(
val long get() = ReadWriteDelegateWrapper(this, reader = { it.toLong() }, writer = { it })
}
-class SafeEnumvConfigDelegate, E : Enum>(
- val config: M,
+class MutableSafeEnumvDelegate, E : Enum>(
+ val meta: M,
private val key: String? = null,
private val default: E,
private val resolver: (String) -> E
) : ReadWriteProperty {
override fun getValue(thisRef: Any?, property: KProperty<*>): E {
- return (config[key ?: property.name]?.string)?.let { resolver(it) } ?: default
+ return (meta[key ?: property.name]?.string)?.let { resolver(it) } ?: default
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: E) {
- config.setValue(key ?: property.name, value.name.asValue())
+ meta.setValue(key ?: property.name, value.name.asValue())
}
}
//Child node delegate
-class MetaNodeDelegate>(
- val config: M,
+class MutableNodeDelegate>(
+ val meta: M,
private val key: String? = null
-) : ReadWriteProperty {
- override fun getValue(thisRef: Any?, property: KProperty<*>): Meta {
- return config[key ?: property.name]?.node ?: EmptyMeta
+) : ReadWriteProperty {
+ override fun getValue(thisRef: Any?, property: KProperty<*>): Meta? {
+ return meta[key ?: property.name]?.node
}
- override fun setValue(thisRef: Any?, property: KProperty<*>, value: Meta) {
- config[key ?: property.name] = value
+ override fun setValue(thisRef: Any?, property: KProperty<*>, value: Meta?) {
+ meta[key ?: property.name] = value
}
}
-class ChildConfigDelegate, T : Configurable>(
- val config: M,
+class MutableMorphDelegate, T : Configurable>(
+ val meta: M,
private val key: String? = null,
private val converter: (Meta) -> T
) :
ReadWriteProperty {
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
- return converter(config[key ?: property.name]?.node ?: EmptyMeta)
+ return converter(meta[key ?: property.name]?.node ?: EmptyMeta)
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
- config[key ?: property.name] = value.config
+ meta[key ?: property.name] = value.config
}
}
@@ -374,45 +374,43 @@ class ReadWriteDelegateWrapper(
* A property delegate that uses custom key
*/
fun > M.value(default: Value = Null, key: String? = null) =
- ValueConfigDelegate(this, key, default)
+ MutableValueDelegate(this, key, default)
fun > M.string(default: String? = null, key: String? = null) =
- StringConfigDelegate(this, key, default)
+ MutableStringDelegate(this, key, default)
fun > M.boolean(default: Boolean? = null, key: String? = null) =
- BooleanConfigDelegate(this, key, default)
+ MutableBooleanDelegate(this, key, default)
fun > M.number(default: Number? = null, key: String? = null) =
- NumberConfigDelegate(this, key, default)
+ MutableNumberDelegate(this, key, default)
-fun > M.child(key: String? = null) = MetaNodeDelegate(this, key)
-
-//fun Configurable.spec(spec: Specification, key: String? = null) = ChildConfigDelegate(key) { spec.wrap(this) }
+fun > M.node(key: String? = null) = MutableNodeDelegate(this, key)
@JvmName("safeString")
fun > M.string(default: String, key: String? = null) =
- SafeStringConfigDelegate(this, key) { default }
+ MutableSafeStringDelegate(this, key) { default }
@JvmName("safeBoolean")
fun > M.boolean(default: Boolean, key: String? = null) =
- SafeBooleanConfigDelegate(this, key) { default }
+ MutableSafeBooleanDelegate(this, key) { default }
@JvmName("safeNumber")
fun > M.number(default: Number, key: String? = null) =
- SafeNumberConfigDelegate(this, key) { default }
+ MutableSafeNumberDelegate(this, key) { default }
@JvmName("safeString")
fun > M.string(key: String? = null, default: () -> String) =
- SafeStringConfigDelegate(this, key, default)
+ MutableSafeStringDelegate(this, key, default)
@JvmName("safeBoolean")
fun > M.boolean(key: String? = null, default: () -> Boolean) =
- SafeBooleanConfigDelegate(this, key, default)
+ MutableSafeBooleanDelegate(this, key, default)
@JvmName("safeNumber")
fun > M.number(key: String? = null, default: () -> Number) =
- SafeNumberConfigDelegate(this, key, default)
+ MutableSafeNumberDelegate(this, key, default)
inline fun , reified E : Enum> M.enum(default: E, key: String? = null) =
- SafeEnumvConfigDelegate(this, key, default) { enumValueOf(it) }
+ MutableSafeEnumvDelegate(this, key, default) { enumValueOf(it) }
diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ExtraMetaDelegates.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ExtraMetaDelegates.kt
index d0eaa54e..6e24c6d0 100644
--- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ExtraMetaDelegates.kt
+++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ExtraMetaDelegates.kt
@@ -33,4 +33,4 @@ fun Configurable.stringList(vararg default: String = emptyArray(), key: String?
fun Metoid.child(key: String? = null, converter: (Meta) -> T) = ChildDelegate(meta, key, converter)
fun Configurable.child(key: String? = null, converter: (Meta) -> T) =
- ChildConfigDelegate(config, key, converter)
+ MutableMorphDelegate(config, key, converter)
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 2e7f452f..1d26b2b7 100644
--- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt
+++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt
@@ -125,6 +125,8 @@ operator fun > M.set(name: Name, value: Any?) {
}
}
+operator fun > M.set(name: NameToken, value: Any?) = set(Name(key), value)
+
operator fun > M.set(key: String, value: Any?) = set(key.toName(), value)
/**
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 f1e2beaf..a578b119 100644
--- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt
+++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt
@@ -59,4 +59,4 @@ fun , C : Specification> Specification.spec(
spec: SpecificationCompanion,
key: String? = null
) =
- ChildConfigDelegate(config, key) { spec.wrap(config) }
\ No newline at end of file
+ MutableMorphDelegate(config, key) { spec.wrap(config) }
\ 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 ba802f5f..dcc36a5a 100644
--- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Styled.kt
+++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Styled.kt
@@ -48,7 +48,7 @@ class Styled(val base: Meta, val style: Config = Config().empty()) : MutableMeta
}
}
-fun Styled.configure(meta: Meta) = apply { style.update(style) }
+fun Styled.configure(meta: Meta) = apply { style.update(meta) }
fun Meta.withStyle(style: Meta = EmptyMeta) = if (this is Styled) {
this.apply { this.configure(style) }
diff --git a/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/jsMeta.kt b/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/jsMeta.kt
index 9002fec1..0858f67a 100644
--- a/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/jsMeta.kt
+++ b/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/jsMeta.kt
@@ -1,8 +1,6 @@
package hep.dataforge.meta
-
-
fun Meta.toDynamic(): dynamic {
fun MetaItem<*>.toDynamic(): dynamic = when (this) {
is MetaItem.ValueItem -> this.value.value.asDynamic()