Refactor Meta delegates
This commit is contained in:
parent
b83821af51
commit
fe6760eee6
@ -61,7 +61,7 @@ class NodeDescriptor : ItemDescriptor() {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
var default: Config? by nullableConfig()
|
var default: Config? by config()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The map of children node descriptors
|
* The map of children node descriptors
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
package hep.dataforge.meta
|
package hep.dataforge.meta
|
||||||
|
|
||||||
|
import hep.dataforge.descriptors.Described
|
||||||
|
import hep.dataforge.descriptors.NodeDescriptor
|
||||||
|
import hep.dataforge.descriptors.defaultItem
|
||||||
|
import hep.dataforge.descriptors.get
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
|
|
||||||
@ -9,7 +13,7 @@ import hep.dataforge.names.toName
|
|||||||
* It is not possible to know if some property is declared by provider just by looking on [Configurable],
|
* It is not possible to know if some property is declared by provider just by looking on [Configurable],
|
||||||
* this information should be provided externally.
|
* this information should be provided externally.
|
||||||
*/
|
*/
|
||||||
interface Configurable {
|
interface Configurable : Described {
|
||||||
/**
|
/**
|
||||||
* Backing config
|
* Backing config
|
||||||
*/
|
*/
|
||||||
@ -19,12 +23,15 @@ interface Configurable {
|
|||||||
* Default meta item provider
|
* Default meta item provider
|
||||||
*/
|
*/
|
||||||
fun getDefaultItem(name: Name): MetaItem<*>? = null
|
fun getDefaultItem(name: Name): MetaItem<*>? = null
|
||||||
|
|
||||||
|
override val descriptor: NodeDescriptor? get() = null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a property with default
|
* Get a property with default
|
||||||
*/
|
*/
|
||||||
fun Configurable.getProperty(name: Name): MetaItem<*>? = config[name] ?: getDefaultItem(name)
|
fun Configurable.getProperty(name: Name): MetaItem<*>? =
|
||||||
|
config[name] ?: getDefaultItem(name) ?: descriptor?.get(name)?.defaultItem()
|
||||||
|
|
||||||
fun Configurable.getProperty(key: String) = getProperty(key.toName())
|
fun Configurable.getProperty(key: String) = getProperty(key.toName())
|
||||||
|
|
||||||
|
@ -28,19 +28,6 @@ open class ConfigurableDelegate(
|
|||||||
val name = key ?: property.name.asName()
|
val name = key ?: property.name.asName()
|
||||||
owner.setProperty(name, value)
|
owner.setProperty(name, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> transform(
|
|
||||||
writer: (T) -> MetaItem<*>? = { MetaItem.of(it) },
|
|
||||||
reader: (MetaItem<*>?) -> T
|
|
||||||
): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
|
||||||
return reader(this@ConfigurableDelegate.getValue(thisRef, property))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
|
||||||
this@ConfigurableDelegate.setValue(thisRef, property, writer(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class LazyConfigurableDelegate(
|
class LazyConfigurableDelegate(
|
||||||
@ -55,7 +42,7 @@ class LazyConfigurableDelegate(
|
|||||||
* A property delegate that uses custom key
|
* A property delegate that uses custom key
|
||||||
*/
|
*/
|
||||||
fun Configurable.item(default: Any?, key: Name? = null): ConfigurableDelegate =
|
fun Configurable.item(default: Any?, key: Name? = null): ConfigurableDelegate =
|
||||||
ConfigurableDelegate(this, key, MetaItem.of(default))
|
ConfigurableDelegate(this, key, default?.let { MetaItem.of(it) })
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generation of item delegate with lazy default.
|
* Generation of item delegate with lazy default.
|
||||||
@ -70,7 +57,7 @@ fun <T> Configurable.item(
|
|||||||
writer: (T) -> MetaItem<*>? = { MetaItem.of(it) },
|
writer: (T) -> MetaItem<*>? = { MetaItem.of(it) },
|
||||||
reader: (MetaItem<*>?) -> T
|
reader: (MetaItem<*>?) -> T
|
||||||
): ReadWriteProperty<Any?, T> =
|
): ReadWriteProperty<Any?, T> =
|
||||||
ConfigurableDelegate(this, key, default?.let { MetaItem.of(it) }).transform(reader = reader, writer = writer)
|
ConfigurableDelegate(this, key, default?.let { MetaItem.of(it) }).map(reader = reader, writer = writer)
|
||||||
|
|
||||||
fun Configurable.value(default: Any? = null, key: Name? = null): ReadWriteProperty<Any?, Value?> =
|
fun Configurable.value(default: Any? = null, key: Name? = null): ReadWriteProperty<Any?, Value?> =
|
||||||
item(default, key).transform { it.value }
|
item(default, key).transform { it.value }
|
||||||
@ -81,7 +68,7 @@ fun <T> Configurable.value(
|
|||||||
writer: (T) -> Value? = { Value.of(it) },
|
writer: (T) -> Value? = { Value.of(it) },
|
||||||
reader: (Value?) -> T
|
reader: (Value?) -> T
|
||||||
): ReadWriteProperty<Any?, T> =
|
): ReadWriteProperty<Any?, T> =
|
||||||
ConfigurableDelegate(this, key, default?.let { MetaItem.of(it) }).transform(
|
ConfigurableDelegate(this, key, default?.let { MetaItem.of(it) }).map(
|
||||||
reader = { reader(it.value) },
|
reader = { reader(it.value) },
|
||||||
writer = { writer(it)?.let { MetaItem.ValueItem(it) } }
|
writer = { writer(it)?.let { MetaItem.ValueItem(it) } }
|
||||||
)
|
)
|
||||||
@ -194,31 +181,9 @@ fun Configurable.doubleArray(vararg doubles: Double, key: Name? = null): ReadWri
|
|||||||
|
|
||||||
/* Node delegates */
|
/* Node delegates */
|
||||||
|
|
||||||
fun Configurable.nullableConfig(key: Name? = null): ReadWriteProperty<Any?, Config?> =
|
fun Configurable.config(key: Name? = null): ReadWriteProperty<Any?, Config?> =
|
||||||
object : ReadWriteProperty<Any?, Config?> {
|
config.node(key)
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Config? {
|
|
||||||
val name = key ?: property.name.asName()
|
|
||||||
return config[name].node
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Config?) {
|
|
||||||
val name = key ?: property.name.asName()
|
|
||||||
config[name] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Configurable.config(key: Name? = null, default: Config.() -> Unit = {}): ReadWriteProperty<Any?, Config> =
|
|
||||||
object : ReadWriteProperty<Any?, Config> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Config {
|
|
||||||
val name = key ?: property.name.asName()
|
|
||||||
return config[name].node ?: Config().apply(default).also { config[name] = it }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Config) {
|
|
||||||
val name = key ?: property.name.asName()
|
|
||||||
config[name] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: Name? = null): ReadWriteProperty<Any?, T?> =
|
fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: Name? = null): ReadWriteProperty<Any?, T?> =
|
||||||
object : ReadWriteProperty<Any?, T?> {
|
object : ReadWriteProperty<Any?, T?> {
|
@ -5,6 +5,7 @@ import hep.dataforge.names.NameToken
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A meta laminate consisting of multiple immutable meta layers. For mutable front layer, use [Scheme].
|
* A meta laminate consisting of multiple immutable meta layers. For mutable front layer, use [Scheme].
|
||||||
|
* If [layers] list contains a [Laminate] it is flat-mapped.
|
||||||
*/
|
*/
|
||||||
class Laminate(layers: List<Meta>) : MetaBase() {
|
class Laminate(layers: List<Meta>) : MetaBase() {
|
||||||
|
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
package hep.dataforge.meta
|
||||||
|
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.asName
|
||||||
|
import hep.dataforge.values.Value
|
||||||
|
import kotlin.jvm.JvmName
|
||||||
|
import kotlin.properties.ReadOnlyProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
/* Meta delegates */
|
||||||
|
|
||||||
|
open class MetaDelegate(
|
||||||
|
open val owner: Meta,
|
||||||
|
val key: Name? = null,
|
||||||
|
open val default: MetaItem<*>? = null
|
||||||
|
) : ReadOnlyProperty<Any?, MetaItem<*>?> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): MetaItem<*>? {
|
||||||
|
return owner[key ?: property.name.asName()] ?: default
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LazyMetaDelegate(
|
||||||
|
owner: Meta,
|
||||||
|
key: Name? = null,
|
||||||
|
defaultProvider: () -> MetaItem<*>? = { null }
|
||||||
|
) : MetaDelegate(owner, key) {
|
||||||
|
override val default by lazy(defaultProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
class DelegateWrapper<T, R>(
|
||||||
|
val delegate: ReadOnlyProperty<Any?, T>,
|
||||||
|
val reader: (T) -> R
|
||||||
|
) : ReadOnlyProperty<Any?, R> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): R {
|
||||||
|
return reader(delegate.getValue(thisRef, property))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, R> ReadOnlyProperty<Any?, T>.map(reader: (T) -> R): DelegateWrapper<T, R> =
|
||||||
|
DelegateWrapper(this, reader)
|
||||||
|
|
||||||
|
|
||||||
|
fun Meta.item(default: Any? = null, key: Name? = null): MetaDelegate =
|
||||||
|
MetaDelegate(this, key, default?.let { MetaItem.of(it) })
|
||||||
|
|
||||||
|
fun Meta.lazyItem(key: Name? = null, defaultProvider: () -> Any?): LazyMetaDelegate =
|
||||||
|
LazyMetaDelegate(this, key) { defaultProvider()?.let { MetaItem.of(it) } }
|
||||||
|
|
||||||
|
//TODO add caching for sealed nodes
|
||||||
|
|
||||||
|
|
||||||
|
//Read-only delegates for Metas
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A property delegate that uses custom key
|
||||||
|
*/
|
||||||
|
fun Meta.value(default: Value? = null, key: Name? = null) =
|
||||||
|
item(default, key).map { it.value }
|
||||||
|
|
||||||
|
fun Meta.string(default: String? = null, key: Name? = null) =
|
||||||
|
item(default, key).map { it.string }
|
||||||
|
|
||||||
|
fun Meta.boolean(default: Boolean? = null, key: Name? = null) =
|
||||||
|
item(default, key).map { it.boolean }
|
||||||
|
|
||||||
|
fun Meta.number(default: Number? = null, key: Name? = null) =
|
||||||
|
item(default, key).map { it.number }
|
||||||
|
|
||||||
|
fun Meta.node(key: Name? = null) =
|
||||||
|
item(key).map { it.node }
|
||||||
|
|
||||||
|
@JvmName("safeString")
|
||||||
|
fun Meta.string(default: String, key: Name? = null) =
|
||||||
|
item(default, key).map { it.string!! }
|
||||||
|
|
||||||
|
@JvmName("safeBoolean")
|
||||||
|
fun Meta.boolean(default: Boolean, key: Name? = null) =
|
||||||
|
item(default, key).map { it.boolean!! }
|
||||||
|
|
||||||
|
@JvmName("safeNumber")
|
||||||
|
fun Meta.number(default: Number, key: Name? = null) =
|
||||||
|
item(default, key).map { it.number!! }
|
||||||
|
|
||||||
|
@JvmName("lazyString")
|
||||||
|
fun Meta.string(key: Name? = null, default: () -> String) =
|
||||||
|
lazyItem(key, default).map { it.string!! }
|
||||||
|
|
||||||
|
@JvmName("lazyBoolean")
|
||||||
|
fun Meta.boolean(key: Name? = null, default: () -> Boolean) =
|
||||||
|
lazyItem(key, default).map { it.boolean!! }
|
||||||
|
|
||||||
|
@JvmName("lazyNumber")
|
||||||
|
fun Meta.number(key: Name? = null, default: () -> Number) =
|
||||||
|
lazyItem(key, default).map { it.number!! }
|
||||||
|
|
||||||
|
|
||||||
|
inline fun <reified E : Enum<E>> Meta.enum(default: E, key: Name? = null) =
|
||||||
|
item(default, key).map { it.enum<E>()!! }
|
@ -0,0 +1,108 @@
|
|||||||
|
package hep.dataforge.meta
|
||||||
|
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.asName
|
||||||
|
import hep.dataforge.values.Value
|
||||||
|
import kotlin.jvm.JvmName
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
/* Read-write delegates */
|
||||||
|
|
||||||
|
open class MutableMetaDelegate<M : MutableMeta<M>>(
|
||||||
|
override val owner: M,
|
||||||
|
key: Name? = null,
|
||||||
|
default: MetaItem<*>? = null
|
||||||
|
) : MetaDelegate(owner, key, default), ReadWriteProperty<Any?, MetaItem<*>?> {
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: MetaItem<*>?) {
|
||||||
|
val name = key ?: property.name.asName()
|
||||||
|
owner.setItem(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class LazyMutableMetaDelegate<M : MutableMeta<M>>(
|
||||||
|
owner: M,
|
||||||
|
key: Name? = null,
|
||||||
|
defaultProvider: () -> MetaItem<*>? = { null }
|
||||||
|
) : MutableMetaDelegate<M>(owner, key) {
|
||||||
|
override val default by lazy(defaultProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReadWriteDelegateWrapper<T, R>(
|
||||||
|
val delegate: ReadWriteProperty<Any?, T>,
|
||||||
|
val reader: (T) -> R,
|
||||||
|
val writer: (R) -> T
|
||||||
|
) : ReadWriteProperty<Any?, R> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): R {
|
||||||
|
return reader(delegate.getValue(thisRef, property))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: R) {
|
||||||
|
delegate.setValue(thisRef, property, writer(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, R> ReadWriteProperty<Any?, T>.map(reader: (T) -> R, writer: (R) -> T): ReadWriteDelegateWrapper<T, R> =
|
||||||
|
ReadWriteDelegateWrapper(this, reader, writer)
|
||||||
|
|
||||||
|
fun <R> ReadWriteProperty<Any?, MetaItem<*>?>.transform(reader: (MetaItem<*>?) -> R): ReadWriteProperty<Any?, R> =
|
||||||
|
map(reader = reader, writer = { MetaItem.of(it) })
|
||||||
|
|
||||||
|
fun <R> ReadWriteProperty<Any?, Value?>.transform(reader: (Value?) -> R) =
|
||||||
|
map(reader = reader, writer = { Value.of(it) })
|
||||||
|
|
||||||
|
|
||||||
|
fun <M : MutableMeta<M>> M.item(default: Any? = null, key: Name? = null): MutableMetaDelegate<M> =
|
||||||
|
MutableMetaDelegate(this, key, default?.let { MetaItem.of(it) })
|
||||||
|
|
||||||
|
fun <M : MutableMeta<M>> M.lazyItem(key: Name? = null, defaultProvider: () -> Any?): LazyMutableMetaDelegate<M> =
|
||||||
|
LazyMutableMetaDelegate(this, key) { defaultProvider()?.let { MetaItem.of(it) } }
|
||||||
|
|
||||||
|
//Read-write delegates
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A property delegate that uses custom key
|
||||||
|
*/
|
||||||
|
fun <M : MutableMeta<M>> M.value(default: Value? = null, key: Name? = null): ReadWriteProperty<Any?, Value?> =
|
||||||
|
item(default, key).transform { it.value }
|
||||||
|
|
||||||
|
fun <M : MutableMeta<M>> M.string(default: String? = null, key: Name? = null): ReadWriteProperty<Any?, String?> =
|
||||||
|
item(default, key).transform { it.string }
|
||||||
|
|
||||||
|
fun <M : MutableMeta<M>> M.boolean(default: Boolean? = null, key: Name? = null): ReadWriteProperty<Any?, Boolean?> =
|
||||||
|
item(default, key).transform { it.boolean }
|
||||||
|
|
||||||
|
fun <M : MutableMeta<M>> M.number(default: Number? = null, key: Name? = null): ReadWriteProperty<Any?, Number?> =
|
||||||
|
item(default, key).transform { it.number }
|
||||||
|
|
||||||
|
inline fun <reified M : MutableMeta<M>> M.node(key: Name? = null) =
|
||||||
|
item(this, key).transform { it.node as? M }
|
||||||
|
|
||||||
|
@JvmName("safeString")
|
||||||
|
fun <M : MutableMeta<M>> M.string(default: String, key: Name? = null) =
|
||||||
|
item(default, key).transform { it.string!! }
|
||||||
|
|
||||||
|
@JvmName("safeBoolean")
|
||||||
|
fun <M : MutableMeta<M>> M.boolean(default: Boolean, key: Name? = null) =
|
||||||
|
item(default, key).transform { it.boolean!! }
|
||||||
|
|
||||||
|
@JvmName("safeNumber")
|
||||||
|
fun <M : MutableMeta<M>> M.number(default: Number, key: Name? = null) =
|
||||||
|
item(default, key).transform { it.number!! }
|
||||||
|
|
||||||
|
@JvmName("lazyString")
|
||||||
|
fun <M : MutableMeta<M>> M.string(key: Name? = null, default: () -> String) =
|
||||||
|
lazyItem(key, default).transform { it.string!! }
|
||||||
|
|
||||||
|
@JvmName("safeBoolean")
|
||||||
|
fun <M : MutableMeta<M>> M.boolean(key: Name? = null, default: () -> Boolean) =
|
||||||
|
lazyItem(key, default).transform { it.boolean!! }
|
||||||
|
|
||||||
|
@JvmName("safeNumber")
|
||||||
|
fun <M : MutableMeta<M>> M.number(key: Name? = null, default: () -> Number) =
|
||||||
|
lazyItem(key, default).transform { it.number!! }
|
||||||
|
|
||||||
|
|
||||||
|
inline fun <M : MutableMeta<M>, reified E : Enum<E>> M.enum(default: E, key: Name? = null) =
|
||||||
|
item(default, key).transform { it.enum<E>()!! }
|
@ -5,6 +5,9 @@ import hep.dataforge.names.Name
|
|||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A base for delegate-based or descriptor-based scheme. [Scheme] has an empty constructor to simplify usage from [Specification].
|
||||||
|
*/
|
||||||
open class Scheme() : Configurable, Described {
|
open class Scheme() : Configurable, Described {
|
||||||
constructor(config: Config, defaultProvider: (Name) -> MetaItem<*>?) : this() {
|
constructor(config: Config, defaultProvider: (Name) -> MetaItem<*>?) : this() {
|
||||||
this.config = config
|
this.config = config
|
||||||
@ -14,13 +17,14 @@ open class Scheme() : Configurable, Described {
|
|||||||
//constructor(config: Config, default: Meta) : this(config, { default[it] })
|
//constructor(config: Config, default: Meta) : this(config, { default[it] })
|
||||||
constructor(config: Config) : this(config, { null })
|
constructor(config: Config) : this(config, { null })
|
||||||
|
|
||||||
final override lateinit var config: Config
|
final override var config: Config = Config()
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
lateinit var defaultProvider: (Name) -> MetaItem<*>?
|
lateinit var defaultProvider: (Name) -> MetaItem<*>?
|
||||||
internal set
|
internal set
|
||||||
|
|
||||||
override val descriptor: NodeDescriptor? = null
|
final override var descriptor: NodeDescriptor? = null
|
||||||
|
internal set
|
||||||
|
|
||||||
override fun getDefaultItem(name: Name): MetaItem<*>? {
|
override fun getDefaultItem(name: Name): MetaItem<*>? {
|
||||||
return defaultProvider(name) ?: descriptor?.get(name)?.defaultItem()
|
return defaultProvider(name) ?: descriptor?.get(name)?.defaultItem()
|
||||||
@ -60,15 +64,21 @@ open class SchemeSpec<T : Scheme>(val builder: () -> T) : Specification<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A scheme that uses [Meta] as a default layer
|
||||||
|
*/
|
||||||
open class MetaScheme(
|
open class MetaScheme(
|
||||||
val meta: Meta,
|
val meta: Meta,
|
||||||
override val descriptor: NodeDescriptor? = null,
|
descriptor: NodeDescriptor? = null,
|
||||||
config: Config = Config()
|
config: Config = Config()
|
||||||
) : Scheme(config, meta::get) {
|
) : Scheme(config, meta::get) {
|
||||||
override val defaultLayer: Meta get() = meta
|
init {
|
||||||
|
this.descriptor = descriptor
|
||||||
|
}
|
||||||
|
override val defaultLayer: Meta get() = Laminate(meta, descriptor?.defaultItem().node)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Meta.toScheme() = MetaScheme(this)
|
fun Meta.asScheme() = MetaScheme(this)
|
||||||
|
|
||||||
fun <T : Configurable> Meta.toScheme(spec: Specification<T>, block: T.() -> Unit) = spec.wrap(this).apply(block)
|
fun <T : Configurable> Meta.toScheme(spec: Specification<T>, block: T.() -> Unit) = spec.wrap(this).apply(block)
|
||||||
|
|
||||||
|
@ -3,14 +3,6 @@ package hep.dataforge.meta
|
|||||||
import hep.dataforge.descriptors.NodeDescriptor
|
import hep.dataforge.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
|
|
||||||
///**
|
|
||||||
// * Find all elements with given body
|
|
||||||
// */
|
|
||||||
//private fun Meta.byBody(body: String): Map<String, MetaItem<*>> =
|
|
||||||
// items.filter { it.key.body == body }.mapKeys { it.key.index }
|
|
||||||
//
|
|
||||||
//private fun Meta.distinctNames() = items.keys.map { it.body }.distinct()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert meta to map of maps
|
* Convert meta to map of maps
|
||||||
*/
|
*/
|
||||||
|
@ -1,414 +0,0 @@
|
|||||||
package hep.dataforge.meta
|
|
||||||
|
|
||||||
import hep.dataforge.names.Name
|
|
||||||
import hep.dataforge.names.asName
|
|
||||||
import hep.dataforge.values.Null
|
|
||||||
import hep.dataforge.values.Value
|
|
||||||
import hep.dataforge.values.asValue
|
|
||||||
import kotlin.jvm.JvmName
|
|
||||||
import kotlin.properties.ReadOnlyProperty
|
|
||||||
import kotlin.properties.ReadWriteProperty
|
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
|
|
||||||
/* Meta delegates */
|
|
||||||
|
|
||||||
//TODO add caching for sealed nodes
|
|
||||||
|
|
||||||
class ValueDelegate(val meta: Meta, private val key: String? = null, private val default: Value? = null) :
|
|
||||||
ReadOnlyProperty<Any?, Value?> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Value? {
|
|
||||||
return meta[key ?: property.name]?.value ?: default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class StringDelegate(val meta: Meta, private val key: String? = null, private val default: String? = null) :
|
|
||||||
ReadOnlyProperty<Any?, String?> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): String? {
|
|
||||||
return meta[key ?: property.name]?.string ?: default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BooleanDelegate(
|
|
||||||
val meta: Meta,
|
|
||||||
private val key: String? = null,
|
|
||||||
private val default: Boolean? = null
|
|
||||||
) : ReadOnlyProperty<Any?, Boolean?> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean? {
|
|
||||||
return meta[key ?: property.name]?.boolean ?: default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NumberDelegate(
|
|
||||||
val meta: Meta,
|
|
||||||
private val key: String? = null,
|
|
||||||
private val default: Number? = null
|
|
||||||
) : ReadOnlyProperty<Any?, Number?> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Number? {
|
|
||||||
return meta[key ?: property.name]?.number ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
//delegates for number transformation
|
|
||||||
|
|
||||||
val double get() = DelegateWrapper(this) { it?.toDouble() }
|
|
||||||
val int get() = DelegateWrapper(this) { it?.toInt() }
|
|
||||||
val short get() = DelegateWrapper(this) { it?.toShort() }
|
|
||||||
val long get() = DelegateWrapper(this) { it?.toLong() }
|
|
||||||
}
|
|
||||||
|
|
||||||
class DelegateWrapper<T, R>(val delegate: ReadOnlyProperty<Any?, T>, val reader: (T) -> R) :
|
|
||||||
ReadOnlyProperty<Any?, R> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): R {
|
|
||||||
return reader(delegate.getValue(thisRef, property))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Delegates with non-null values
|
|
||||||
|
|
||||||
class SafeStringDelegate(
|
|
||||||
val meta: Meta,
|
|
||||||
private val key: String? = null,
|
|
||||||
default: () -> String
|
|
||||||
) : ReadOnlyProperty<Any?, String> {
|
|
||||||
|
|
||||||
private val default: String by lazy(default)
|
|
||||||
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): String {
|
|
||||||
return meta[key ?: property.name]?.string ?: default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SafeBooleanDelegate(
|
|
||||||
val meta: Meta,
|
|
||||||
private val key: String? = null,
|
|
||||||
default: () -> Boolean
|
|
||||||
) : ReadOnlyProperty<Any?, Boolean> {
|
|
||||||
|
|
||||||
private val default: Boolean by lazy(default)
|
|
||||||
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
|
|
||||||
return meta[key ?: property.name]?.boolean ?: default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class SafeNumberDelegate(
|
|
||||||
val meta: Meta,
|
|
||||||
private val key: String? = null,
|
|
||||||
default: () -> Number
|
|
||||||
) : ReadOnlyProperty<Any?, Number> {
|
|
||||||
|
|
||||||
private val default: Number by lazy(default)
|
|
||||||
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Number {
|
|
||||||
return meta[key ?: property.name]?.number ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
val double get() = DelegateWrapper(this) { it.toDouble() }
|
|
||||||
val int get() = DelegateWrapper(this) { it.toInt() }
|
|
||||||
val short get() = DelegateWrapper(this) { it.toShort() }
|
|
||||||
val long get() = DelegateWrapper(this) { it.toLong() }
|
|
||||||
}
|
|
||||||
|
|
||||||
class SafeEnumDelegate<E : Enum<E>>(
|
|
||||||
val meta: Meta,
|
|
||||||
private val key: String? = null,
|
|
||||||
private val default: E,
|
|
||||||
private val resolver: (String) -> E
|
|
||||||
) : ReadOnlyProperty<Any?, E> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): E {
|
|
||||||
return (meta[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Child node delegate
|
|
||||||
|
|
||||||
class ChildDelegate<T>(
|
|
||||||
val meta: Meta,
|
|
||||||
private val key: String? = null,
|
|
||||||
private val converter: (Meta) -> T
|
|
||||||
) : ReadOnlyProperty<Any?, T?> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
|
|
||||||
return meta[key ?: property.name]?.node?.let { converter(it) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Read-only delegates for Metas
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A property delegate that uses custom key
|
|
||||||
*/
|
|
||||||
fun Meta.value(default: Value = Null, key: String? = null) = ValueDelegate(this, key, default)
|
|
||||||
|
|
||||||
fun Meta.string(default: String? = null, key: String? = null) = StringDelegate(this, key, default)
|
|
||||||
|
|
||||||
fun Meta.boolean(default: Boolean? = null, key: String? = null) = BooleanDelegate(this, key, default)
|
|
||||||
|
|
||||||
fun Meta.number(default: Number? = null, key: String? = null) = NumberDelegate(this, key, default)
|
|
||||||
|
|
||||||
fun Meta.child(key: String? = null) = ChildDelegate(this, key) { it }
|
|
||||||
|
|
||||||
@JvmName("safeString")
|
|
||||||
fun Meta.string(default: String, key: String? = null) =
|
|
||||||
SafeStringDelegate(this, key) { default }
|
|
||||||
|
|
||||||
@JvmName("safeBoolean")
|
|
||||||
fun Meta.boolean(default: Boolean, key: String? = null) =
|
|
||||||
SafeBooleanDelegate(this, key) { default }
|
|
||||||
|
|
||||||
@JvmName("safeNumber")
|
|
||||||
fun Meta.number(default: Number, key: String? = null) =
|
|
||||||
SafeNumberDelegate(this, key) { default }
|
|
||||||
|
|
||||||
@JvmName("safeString")
|
|
||||||
fun Meta.string(key: String? = null, default: () -> String) =
|
|
||||||
SafeStringDelegate(this, key, default)
|
|
||||||
|
|
||||||
@JvmName("safeBoolean")
|
|
||||||
fun Meta.boolean(key: String? = null, default: () -> Boolean) =
|
|
||||||
SafeBooleanDelegate(this, key, default)
|
|
||||||
|
|
||||||
@JvmName("safeNumber")
|
|
||||||
fun Meta.number(key: String? = null, default: () -> Number) =
|
|
||||||
SafeNumberDelegate(this, key, default)
|
|
||||||
|
|
||||||
|
|
||||||
inline fun <reified E : Enum<E>> Meta.enum(default: E, key: String? = null) =
|
|
||||||
SafeEnumDelegate(this, key, default) { enumValueOf(it) }
|
|
||||||
|
|
||||||
/* Read-write delegates */
|
|
||||||
|
|
||||||
class MutableValueDelegate<M : MutableMeta<M>>(
|
|
||||||
val meta: M,
|
|
||||||
private val key: Name? = null,
|
|
||||||
private val default: Value? = null
|
|
||||||
) : ReadWriteProperty<Any?, Value?> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Value? {
|
|
||||||
return meta[key ?: property.name.asName()]?.value ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Value?) {
|
|
||||||
val name = key ?: property.name.asName()
|
|
||||||
if (value == null) {
|
|
||||||
meta.remove(name)
|
|
||||||
} else {
|
|
||||||
meta.setValue(name, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> transform(writer: (T) -> Value? = { Value.of(it) }, reader: (Value?) -> T) =
|
|
||||||
ReadWriteDelegateWrapper(this, reader, writer)
|
|
||||||
}
|
|
||||||
|
|
||||||
class MutableStringDelegate<M : MutableMeta<M>>(
|
|
||||||
val meta: M,
|
|
||||||
private val key: Name? = null,
|
|
||||||
private val default: String? = null
|
|
||||||
) : ReadWriteProperty<Any?, String?> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): String? {
|
|
||||||
return meta[key ?: property.name.asName()]?.string ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String?) {
|
|
||||||
val name = key ?: property.name.asName()
|
|
||||||
if (value == null) {
|
|
||||||
meta.remove(name)
|
|
||||||
} else {
|
|
||||||
meta.setValue(name, value.asValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MutableBooleanDelegate<M : MutableMeta<M>>(
|
|
||||||
val meta: M,
|
|
||||||
private val key: Name? = null,
|
|
||||||
private val default: Boolean? = null
|
|
||||||
) : ReadWriteProperty<Any?, Boolean?> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean? {
|
|
||||||
return meta[key ?: property.name.asName()]?.boolean ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean?) {
|
|
||||||
val name = key ?: property.name.asName()
|
|
||||||
if (value == null) {
|
|
||||||
meta.remove(name)
|
|
||||||
} else {
|
|
||||||
meta.setValue(name, value.asValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MutableNumberDelegate<M : MutableMeta<M>>(
|
|
||||||
val meta: M,
|
|
||||||
private val key: Name? = null,
|
|
||||||
private val default: Number? = null
|
|
||||||
) : ReadWriteProperty<Any?, Number?> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Number? {
|
|
||||||
return meta[key ?: property.name.asName()]?.number ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Number?) {
|
|
||||||
val name = key ?: property.name.asName()
|
|
||||||
if (value == null) {
|
|
||||||
meta.remove(name)
|
|
||||||
} else {
|
|
||||||
meta.setValue(name, value.asValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val double get() = ReadWriteDelegateWrapper(this, reader = { it?.toDouble() }, writer = { it })
|
|
||||||
val float get() = ReadWriteDelegateWrapper(this, reader = { it?.toFloat() }, writer = { it })
|
|
||||||
val int get() = ReadWriteDelegateWrapper(this, reader = { it?.toInt() }, writer = { it })
|
|
||||||
val short get() = ReadWriteDelegateWrapper(this, reader = { it?.toShort() }, writer = { it })
|
|
||||||
val long get() = ReadWriteDelegateWrapper(this, reader = { it?.toLong() }, writer = { it })
|
|
||||||
}
|
|
||||||
|
|
||||||
//Delegates with non-null values
|
|
||||||
|
|
||||||
class MutableSafeStringDelegate<M : MutableMeta<M>>(
|
|
||||||
val meta: M,
|
|
||||||
private val key: Name? = null,
|
|
||||||
default: () -> String
|
|
||||||
) : ReadWriteProperty<Any?, String> {
|
|
||||||
|
|
||||||
private val default: String by lazy(default)
|
|
||||||
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): String {
|
|
||||||
return meta[key ?: property.name.asName()]?.string ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
|
||||||
meta.setValue(key ?: property.name.asName(), value.asValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MutableSafeBooleanDelegate<M : MutableMeta<M>>(
|
|
||||||
val meta: M,
|
|
||||||
private val key: Name? = null,
|
|
||||||
default: () -> Boolean
|
|
||||||
) : ReadWriteProperty<Any?, Boolean> {
|
|
||||||
|
|
||||||
private val default: Boolean by lazy(default)
|
|
||||||
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
|
|
||||||
return meta[key ?: property.name.asName()]?.boolean ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
|
|
||||||
meta.setValue(key ?: property.name.asName(), value.asValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MutableSafeNumberDelegate<M : MutableMeta<M>>(
|
|
||||||
val meta: M,
|
|
||||||
private val key: Name? = null,
|
|
||||||
default: () -> Number
|
|
||||||
) : ReadWriteProperty<Any?, Number> {
|
|
||||||
|
|
||||||
private val default: Number by lazy(default)
|
|
||||||
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Number {
|
|
||||||
return meta[key ?: property.name.asName()]?.number ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Number) {
|
|
||||||
meta.setValue(key ?: property.name.asName(), value.asValue())
|
|
||||||
}
|
|
||||||
|
|
||||||
val double get() = ReadWriteDelegateWrapper(this, reader = { it.toDouble() }, writer = { it })
|
|
||||||
val float get() = ReadWriteDelegateWrapper(this, reader = { it.toFloat() }, writer = { it })
|
|
||||||
val int get() = ReadWriteDelegateWrapper(this, reader = { it.toInt() }, writer = { it })
|
|
||||||
val short get() = ReadWriteDelegateWrapper(this, reader = { it.toShort() }, writer = { it })
|
|
||||||
val long get() = ReadWriteDelegateWrapper(this, reader = { it.toLong() }, writer = { it })
|
|
||||||
}
|
|
||||||
|
|
||||||
class MutableSafeEnumvDelegate<M : MutableMeta<M>, E : Enum<E>>(
|
|
||||||
val meta: M,
|
|
||||||
private val key: Name? = null,
|
|
||||||
private val default: E,
|
|
||||||
private val resolver: (String) -> E
|
|
||||||
) : ReadWriteProperty<Any?, E> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): E {
|
|
||||||
return (meta[key ?: property.name.asName()]?.string)?.let { resolver(it) } ?: default
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: E) {
|
|
||||||
meta.setValue(key ?: property.name.asName(), value.name.asValue())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Child node delegate
|
|
||||||
|
|
||||||
class MutableNodeDelegate<M : MutableMeta<M>>(
|
|
||||||
val meta: M,
|
|
||||||
private val key: Name? = null
|
|
||||||
) : ReadWriteProperty<Any?, M?> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): M? {
|
|
||||||
return meta[key ?: property.name.asName()]?.node
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: M?) {
|
|
||||||
meta[key ?: property.name.asName()] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ReadWriteDelegateWrapper<T, R>(
|
|
||||||
val delegate: ReadWriteProperty<Any?, T>,
|
|
||||||
val reader: (T) -> R,
|
|
||||||
val writer: (R) -> T
|
|
||||||
) : ReadWriteProperty<Any?, R> {
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): R {
|
|
||||||
return reader(delegate.getValue(thisRef, property))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: R) {
|
|
||||||
delegate.setValue(thisRef, property, writer(value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//Read-write delegates
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A property delegate that uses custom key
|
|
||||||
*/
|
|
||||||
fun <M : MutableMeta<M>> M.value(default: Value = Null, key: Name? = null) =
|
|
||||||
MutableValueDelegate(this, key, default)
|
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> M.string(default: String? = null, key: Name? = null) =
|
|
||||||
MutableStringDelegate(this, key, default)
|
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> M.boolean(default: Boolean? = null, key: Name? = null) =
|
|
||||||
MutableBooleanDelegate(this, key, default)
|
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> M.number(default: Number? = null, key: Name? = null) =
|
|
||||||
MutableNumberDelegate(this, key, default)
|
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> M.child(key: Name? = null) =
|
|
||||||
MutableNodeDelegate(this, key)
|
|
||||||
|
|
||||||
@JvmName("safeString")
|
|
||||||
fun <M : MutableMeta<M>> M.string(default: String, key: Name? = null) =
|
|
||||||
MutableSafeStringDelegate(this, key) { default }
|
|
||||||
|
|
||||||
@JvmName("safeBoolean")
|
|
||||||
fun <M : MutableMeta<M>> M.boolean(default: Boolean, key: Name? = null) =
|
|
||||||
MutableSafeBooleanDelegate(this, key) { default }
|
|
||||||
|
|
||||||
@JvmName("safeNumber")
|
|
||||||
fun <M : MutableMeta<M>> M.number(default: Number, key: Name? = null) =
|
|
||||||
MutableSafeNumberDelegate(this, key) { default }
|
|
||||||
|
|
||||||
@JvmName("safeString")
|
|
||||||
fun <M : MutableMeta<M>> M.string(key: Name? = null, default: () -> String) =
|
|
||||||
MutableSafeStringDelegate(this, key, default)
|
|
||||||
|
|
||||||
@JvmName("safeBoolean")
|
|
||||||
fun <M : MutableMeta<M>> M.boolean(key: Name? = null, default: () -> Boolean) =
|
|
||||||
MutableSafeBooleanDelegate(this, key, default)
|
|
||||||
|
|
||||||
@JvmName("safeNumber")
|
|
||||||
fun <M : MutableMeta<M>> M.number(key: Name? = null, default: () -> Number) =
|
|
||||||
MutableSafeNumberDelegate(this, key, default)
|
|
||||||
|
|
||||||
|
|
||||||
inline fun <M : MutableMeta<M>, reified E : Enum<E>> M.enum(default: E, key: Name? = null) =
|
|
||||||
MutableSafeEnumvDelegate(this, key, default) { enumValueOf(it) }
|
|
@ -26,26 +26,13 @@ fun Meta.getIndexed(name: Name): Map<String, MetaItem<*>> {
|
|||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun Meta.getIndexed(name: String): Map<String, MetaItem<*>> = this@getIndexed.getIndexed(name.toName())
|
fun Meta.getIndexed(name: String): Map<String, MetaItem<*>> = this@getIndexed.getIndexed(name.toName())
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all items matching given name.
|
* Get all items matching given name.
|
||||||
*/
|
*/
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun <M : MetaNode<M>> M.getIndexed(name: Name): Map<String, MetaItem<M>> {
|
fun <M : MetaNode<M>> M.getIndexed(name: Name): Map<String, MetaItem<M>> =
|
||||||
val root: MetaNode<M>? = when (name.length) {
|
(this as Meta).getIndexed(name) as Map<String, MetaItem<M>>
|
||||||
0 -> error("Can't use empty name for that")
|
|
||||||
1 -> this
|
|
||||||
else -> (this[name.cutLast()] as? MetaItem.NodeItem<M>)?.node
|
|
||||||
}
|
|
||||||
|
|
||||||
val (body, index) = name.last()!!
|
|
||||||
val regex = index.toRegex()
|
|
||||||
|
|
||||||
return root?.items
|
|
||||||
?.filter { it.key.body == body && (index.isEmpty() || regex.matches(it.key.index)) }
|
|
||||||
?.mapKeys { it.key.index }
|
|
||||||
?: emptyMap()
|
|
||||||
}
|
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun <M : MetaNode<M>> M.getIndexed(name: String): Map<String, MetaItem<M>> = getIndexed(name.toName())
|
fun <M : MetaNode<M>> M.getIndexed(name: String): Map<String, MetaItem<M>> = getIndexed(name.toName())
|
@ -13,7 +13,7 @@ class SchemeTest{
|
|||||||
"d" put it
|
"d" put it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.toScheme()
|
}.asScheme()
|
||||||
|
|
||||||
val meta = styled.toMeta()
|
val meta = styled.toMeta()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user