cleanup specification. again
This commit is contained in:
parent
adf65a5bde
commit
9c3f9420ea
@ -9,13 +9,9 @@ import hep.dataforge.names.asName
|
||||
* A base for delegate-based or descriptor-based scheme. [Scheme] has an empty constructor to simplify usage from [Specification].
|
||||
* Default item provider and [NodeDescriptor] are optional
|
||||
*/
|
||||
public open class Scheme(
|
||||
items: MutableItemProvider = Config(),
|
||||
internal var default: ItemProvider? = null,
|
||||
descriptor: NodeDescriptor? = null,
|
||||
) : MutableItemProvider, Described, MetaRepr {
|
||||
public open class Scheme() : MutableItemProvider, Described, MetaRepr {
|
||||
|
||||
public var items: MutableItemProvider = items
|
||||
public var items: MutableItemProvider = MetaBuilder()
|
||||
internal set(value) {
|
||||
//Fix problem with `init` blocks in specifications
|
||||
field = value.apply {
|
||||
@ -23,9 +19,21 @@ public open class Scheme(
|
||||
}
|
||||
}
|
||||
|
||||
override var descriptor: NodeDescriptor? = descriptor
|
||||
internal var default: ItemProvider? = null
|
||||
|
||||
final override var descriptor: NodeDescriptor? = null
|
||||
internal set
|
||||
|
||||
public constructor(
|
||||
items: MutableItemProvider,
|
||||
default: ItemProvider? = null,
|
||||
descriptor: NodeDescriptor? = null,
|
||||
) : this(){
|
||||
this.items = items
|
||||
this.default = default
|
||||
this.descriptor = descriptor
|
||||
}
|
||||
|
||||
|
||||
private fun getDefaultItem(name: Name): MetaItem? {
|
||||
return default?.get(name) ?: descriptor?.get(name)?.defaultItem()
|
||||
@ -114,7 +122,4 @@ public open class SchemeSpec<T : Scheme>(
|
||||
|
||||
public fun Meta.asScheme(): Scheme = Scheme().apply {
|
||||
items = this@asScheme.asConfig()
|
||||
}
|
||||
|
||||
public fun <T : MutableItemProvider> Meta.toScheme(spec: Specification<T>, block: T.() -> Unit = {}): T =
|
||||
spec.read(this).apply(block)
|
||||
}
|
@ -35,8 +35,9 @@ public interface Specification<T : MutableItemProvider> {
|
||||
/**
|
||||
* Update a [MutableItemProvider] using given specification
|
||||
*/
|
||||
public fun <T : MutableItemProvider> MutableItemProvider.update(spec: Specification<T>, action: T.() -> Unit): T =
|
||||
public fun <T : MutableItemProvider> MutableItemProvider.update(spec: Specification<T>, action: T.() -> Unit) {
|
||||
spec.write(this).apply(action)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update configuration using given specification
|
||||
@ -44,38 +45,24 @@ public fun <T : MutableItemProvider> MutableItemProvider.update(spec: Specificat
|
||||
public fun <C : MutableItemProvider, S : Specification<C>> Configurable.update(
|
||||
spec: S,
|
||||
action: C.() -> Unit,
|
||||
): Configurable = apply { config.update(spec, action) }
|
||||
) {
|
||||
config.update(spec, action)
|
||||
}
|
||||
|
||||
public fun <T : MutableItemProvider> TypedMetaItem<Config>.withSpec(spec: Specification<T>): T? =
|
||||
public fun <T : MutableItemProvider> TypedMetaItem<MutableMeta<*>>.withSpec(spec: Specification<T>): T? =
|
||||
node?.let { spec.write(it) }
|
||||
|
||||
public fun <T : Scheme> MutableItemProvider.spec(
|
||||
spec: Specification<T>,
|
||||
key: Name? = null,
|
||||
): ReadWriteProperty<Any?, T?> = object : ReadWriteProperty<Any?, T?> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
|
||||
val name = key ?: property.name.asName()
|
||||
return get(name).node?.let { spec.read(it) }
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
|
||||
val name = key ?: property.name.asName()
|
||||
set(name, value?.toMeta()?.asMetaItem())
|
||||
}
|
||||
}
|
||||
|
||||
public fun <T : Scheme> MutableItemProvider.spec(
|
||||
spec: Specification<T>,
|
||||
default: T,
|
||||
key: Name? = null,
|
||||
): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||
val name = key ?: property.name.asName()
|
||||
return get(name).node?.let { spec.read(it) } ?: default
|
||||
return getChild(name).let { spec.write(it) }
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||
val name = key ?: property.name.asName()
|
||||
set(name, value.toMeta().asMetaItem())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
package hep.dataforge.meta
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
||||
class SchemeTest{
|
||||
@Test
|
||||
fun testMetaScheme(){
|
||||
val styled = Meta {
|
||||
repeat(10){
|
||||
"b.a[$it]" put {
|
||||
"d" put it
|
||||
}
|
||||
}
|
||||
}.asScheme()
|
||||
|
||||
val meta = styled.toMeta()
|
||||
|
||||
assertEquals(10, meta.valueSequence().count())
|
||||
|
||||
val bNode = styled.get("b").node
|
||||
|
||||
val aNodes = bNode?.getIndexed("a")
|
||||
|
||||
val allNodes = meta.getIndexed("b.a")
|
||||
|
||||
assertEquals(3, aNodes?.get("3").node["d"].int)
|
||||
assertEquals(3, allNodes["3"].node["d"].int)
|
||||
}
|
||||
|
||||
}
|
@ -15,6 +15,37 @@ class SpecificationTest {
|
||||
}
|
||||
}
|
||||
|
||||
class TestScheme : Scheme() {
|
||||
var a by int()
|
||||
var b by string()
|
||||
|
||||
companion object : SchemeSpec<TestScheme>(::TestScheme)
|
||||
}
|
||||
|
||||
// @Test
|
||||
// fun testMetaScheme(){
|
||||
// val styled = Meta {
|
||||
// repeat(10){
|
||||
// "b.a[$it]" put {
|
||||
// "d" put it
|
||||
// }
|
||||
// }
|
||||
// }.asScheme()
|
||||
//
|
||||
// val meta = styled.toMeta()
|
||||
//
|
||||
// assertEquals(10, meta.valueSequence().count())
|
||||
//
|
||||
// val bNode = styled["b"].node
|
||||
//
|
||||
// val aNodes = bNode?.getIndexed("a")
|
||||
//
|
||||
// val allNodes = meta.getIndexed("b.a")
|
||||
//
|
||||
// assertEquals(3, aNodes?.get("3").node["d"].int)
|
||||
// assertEquals(3, allNodes["3"].node["d"].int)
|
||||
// }
|
||||
|
||||
|
||||
@Test
|
||||
fun testSpecific() {
|
||||
@ -23,4 +54,15 @@ class SpecificationTest {
|
||||
}
|
||||
assertEquals(emptyList(), testObject.list)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testChildModification() {
|
||||
val config = Config()
|
||||
val child = config.getChild("child")
|
||||
val scheme = TestScheme.write(child)
|
||||
scheme.a = 22
|
||||
scheme.b = "test"
|
||||
assertEquals(22,config["child.a"].int)
|
||||
assertEquals("test",config["child.b"].string)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user