This commit is contained in:
Alexander Nozik 2020-12-24 10:32:11 +03:00
parent 397a19fb32
commit 1c89543d73
8 changed files with 45 additions and 34 deletions

View File

@ -14,6 +14,7 @@
- Moved `Envelope` builder to a top level function. Companion invoke is deprecated. - Moved `Envelope` builder to a top level function. Companion invoke is deprecated.
- Context logging moved to the extension - Context logging moved to the extension
- `number` and `string` methods on `Value` moved to extensions (breaking change) - `number` and `string` methods on `Value` moved to extensions (breaking change)
- \[Major breaking change\] Schemes and configurables us `MutableItemProvider` instead of `Config`
### Deprecated ### Deprecated

View File

@ -129,10 +129,9 @@ public final class hep/dataforge/meta/ItemProviderKt {
public static final fun get (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; public static final fun get (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem;
public static final fun get (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem; public static final fun get (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem;
public static final fun getChild (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/ItemProvider; public static final fun getChild (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/ItemProvider;
public static final fun getChild (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;)Lhep/dataforge/meta/ItemProvider;
public static final fun getIndexed (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Ljava/util/Map; public static final fun getIndexed (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Ljava/util/Map;
public static final fun getIndexed (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;)Ljava/util/Map; public static final fun getIndexed (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;)Ljava/util/Map;
public static final fun getIndexed (Lhep/dataforge/meta/TypedMeta;Lhep/dataforge/names/Name;)Ljava/util/Map;
public static final fun getIndexed (Lhep/dataforge/meta/TypedMeta;Ljava/lang/String;)Ljava/util/Map;
public static final fun getRootNode (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Meta; public static final fun getRootNode (Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Meta;
public static final fun withDefault (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/ItemProvider; public static final fun withDefault (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/ItemProvider;
} }
@ -417,6 +416,7 @@ public abstract interface class hep/dataforge/meta/MutableItemProvider : hep/dat
public final class hep/dataforge/meta/MutableItemProviderKt { public final class hep/dataforge/meta/MutableItemProviderKt {
public static final fun editChild (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; public static final fun editChild (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider;
public static final fun getChild (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MutableItemProvider; public static final fun getChild (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MutableItemProvider;
public static final fun getChild (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;)Lhep/dataforge/meta/MutableItemProvider;
public static final fun remove (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)V public static final fun remove (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)V
public static final fun remove (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;)V public static final fun remove (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;)V
public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V
@ -448,8 +448,8 @@ public final class hep/dataforge/meta/MutableMeta$DefaultImpls {
} }
public final class hep/dataforge/meta/MutableMetaKt { public final class hep/dataforge/meta/MutableMetaKt {
public static final fun append (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Ljava/lang/Object;)V public static final fun append (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Object;)V
public static final fun append (Lhep/dataforge/meta/MutableMeta;Ljava/lang/String;Ljava/lang/Object;)V public static final fun append (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Ljava/lang/Object;)V
public static final fun edit (Lhep/dataforge/meta/AbstractMutableMeta;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V public static final fun edit (Lhep/dataforge/meta/AbstractMutableMeta;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V
} }

View File

@ -69,12 +69,12 @@ public fun ItemProvider.getChild(childName: Name): ItemProvider = get(childName)
public fun ItemProvider.getChild(childName: String): ItemProvider = getChild(childName.toName()) public fun ItemProvider.getChild(childName: String): ItemProvider = getChild(childName.toName())
/** ///**
* Get all items matching given name. // * Get all items matching given name.
*/ // */
@Suppress("UNCHECKED_CAST") //@Suppress("UNCHECKED_CAST")
public fun <M : TypedMeta<M>> M.getIndexed(name: Name): Map<String, MetaItem<M>> = //public fun <M : TypedMeta<M>> M.getIndexed(name: Name): Map<String?, MetaItem<M>> =
(this as Meta).getIndexed(name) as Map<String, MetaItem<M>> // (this as Meta).getIndexed(name) as Map<String?, MetaItem<M>>
//
public fun <M : TypedMeta<M>> M.getIndexed(name: String): Map<String, MetaItem<M>> = //public fun <M : TypedMeta<M>> M.getIndexed(name: String): Map<String?, MetaItem<M>> =
getIndexed(name.toName()) // getIndexed(name.toName())

View File

@ -83,7 +83,7 @@ public fun Meta.valueSequence(): Sequence<Pair<Name, Value>> {
public fun Meta.itemSequence(): Sequence<Pair<Name, MetaItem<*>>> = sequence { public fun Meta.itemSequence(): Sequence<Pair<Name, MetaItem<*>>> = sequence {
items.forEach { (key, item) -> items.forEach { (key, item) ->
yield(key.asName() to item) yield(key.asName() to item)
if (item is NodeItem<*>) { if (item is NodeItem) {
yieldAll(item.node.itemSequence().map { (innerKey, innerItem) -> yieldAll(item.node.itemSequence().map { (innerKey, innerItem) ->
(key + innerKey) to innerItem (key + innerKey) to innerItem
}) })

View File

@ -52,16 +52,16 @@ public sealed class MetaItem<out M : Meta>() {
} }
} }
public fun Value.asMetaItem(): MetaItem.ValueItem = MetaItem.ValueItem(this) public fun Value.asMetaItem(): ValueItem = ValueItem(this)
public fun <M : Meta> M.asMetaItem(): MetaItem.NodeItem<M> = MetaItem.NodeItem(this) public fun <M : Meta> M.asMetaItem(): NodeItem<M> = NodeItem(this)
/** /**
* Unsafe methods to access values and nodes directly from [MetaItem] * Unsafe methods to access values and nodes directly from [MetaItem]
*/ */
public val MetaItem<*>?.value: Value? public val MetaItem<*>?.value: Value?
get() = (this as? MetaItem.ValueItem)?.value get() = (this as? ValueItem)?.value
?: (this?.node?.get(Meta.VALUE_KEY) as? MetaItem.ValueItem)?.value ?: (this?.node?.get(Meta.VALUE_KEY) as? ValueItem)?.value
public val MetaItem<*>?.string: String? get() = value?.string public val MetaItem<*>?.string: String? get() = value?.string
public val MetaItem<*>?.boolean: Boolean? get() = value?.boolean public val MetaItem<*>?.boolean: Boolean? get() = value?.boolean
@ -83,6 +83,6 @@ public val MetaItem<*>.stringList: List<String>? get() = value?.list?.map { it.s
public val <M : Meta> MetaItem<M>?.node: M? public val <M : Meta> MetaItem<M>?.node: M?
get() = when (this) { get() = when (this) {
null -> null null -> null
is MetaItem.ValueItem -> null//error("Trying to interpret value meta item as node item") is ValueItem -> null//error("Trying to interpret value meta item as node item")
is MetaItem.NodeItem -> node is NodeItem -> node
} }

View File

@ -2,6 +2,7 @@ package hep.dataforge.meta
import hep.dataforge.names.* import hep.dataforge.names.*
import hep.dataforge.values.Value import hep.dataforge.values.Value
import hep.dataforge.values.asValue
public interface MutableItemProvider : ItemProvider { public interface MutableItemProvider : ItemProvider {
public fun setItem(name: Name, item: MetaItem<*>?) public fun setItem(name: Name, item: MetaItem<*>?)
@ -29,8 +30,13 @@ public inline fun MutableItemProvider.remove(name: String): Unit = remove(name.t
public operator fun MutableItemProvider.set(name: Name, value: Any?) { public operator fun MutableItemProvider.set(name: Name, value: Any?) {
when (value) { when (value) {
null -> remove(name) null -> remove(name)
is Value -> set(name, value)
is Number -> set(name, value.asValue())
is String -> set(name, value.asValue())
is Boolean -> set(name, value.asValue())
is MetaItem<*> -> set(name, value) is MetaItem<*> -> set(name, value)
is Meta -> set(name, value) is Meta -> set(name, value)
is MetaRepr -> set(name, value.toMeta())
is Configurable -> set(name, value.config) is Configurable -> set(name, value.config)
else -> set(name, Value.of(value)) else -> set(name, Value.of(value))
} }
@ -97,7 +103,7 @@ public fun MutableItemProvider.getChild(childName: Name): MutableItemProvider {
} }
} }
public fun MutableItemProvider.getChild(childName: String): MutableItemProvider = getChild(childName.toName()) public fun MutableItemProvider.getChild(childName: String): MutableItemProvider = getChild(childName.toName())
/** /**
* Update existing mutable node with another node. The rules are following: * Update existing mutable node with another node. The rules are following:

View File

@ -28,7 +28,7 @@ public abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractTypedMet
//itemChanged(key.asName(), oldItem, newItem) //itemChanged(key.asName(), oldItem, newItem)
} }
protected fun wrapItem(item: MetaItem<*>?): MetaItem<M>? = when (item) { private fun wrapItem(item: MetaItem<*>?): MetaItem<M>? = when (item) {
null -> null null -> null
is MetaItem.ValueItem -> item is MetaItem.ValueItem -> item
is MetaItem.NodeItem -> MetaItem.NodeItem(wrapNode(item.node)) is MetaItem.NodeItem -> MetaItem.NodeItem(wrapNode(item.node))
@ -67,18 +67,18 @@ public abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractTypedMet
/** /**
* Append the node with a same-name-sibling, automatically generating numerical index * Append the node with a same-name-sibling, automatically generating numerical index
*/ */
public fun <M : MutableMeta<M>> M.append(name: Name, value: Any?) { public fun MutableItemProvider.append(name: Name, value: Any?) {
require(!name.isEmpty()) { "Name could not be empty for append operation" } require(!name.isEmpty()) { "Name could not be empty for append operation" }
val newIndex = name.lastOrNull()!!.index val newIndex = name.lastOrNull()!!.index
if (newIndex != null) { if (newIndex != null) {
set(name, value) set(name, value)
} else { } else {
val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.maxOrNull() ?: -1) + 1 val index = (getIndexed(name).keys.mapNotNull { it?.toIntOrNull() }.maxOrNull() ?: -1) + 1
set(name.withIndex(index.toString()), value) set(name.withIndex(index.toString()), value)
} }
} }
public fun <M : MutableMeta<M>> M.append(name: String, value: Any?): Unit = append(name.toName(), value) public fun MutableItemProvider.append(name: String, value: Any?): Unit = append(name.toName(), value)
/** /**
* Apply existing node with given [builder] or create a new element with it. * Apply existing node with given [builder] or create a new element with it.

View File

@ -8,7 +8,7 @@ import hep.dataforge.values.*
* A common parent for [ValueDescriptor] and [NodeDescriptor]. Describes a single [MetaItem] or a group of same-name-siblings. * A common parent for [ValueDescriptor] and [NodeDescriptor]. Describes a single [MetaItem] or a group of same-name-siblings.
*/ */
@DFBuilder @DFBuilder
public sealed class ItemDescriptor(final override val config: Config): Configurable { public sealed class ItemDescriptor(final override val config: Config) : Configurable {
/** /**
* True if same name siblings with this name are allowed * True if same name siblings with this name are allowed
@ -40,7 +40,7 @@ public sealed class ItemDescriptor(final override val config: Config): Configura
public abstract fun copy(): ItemDescriptor public abstract fun copy(): ItemDescriptor
public companion object{ public companion object {
public const val DEFAULT_INDEX_KEY: String = "@index" public const val DEFAULT_INDEX_KEY: String = "@index"
} }
} }
@ -95,12 +95,13 @@ public class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config)
* The map of children item descriptors (both nodes and values) * The map of children item descriptors (both nodes and values)
*/ */
public val items: Map<String, ItemDescriptor> public val items: Map<String, ItemDescriptor>
get() = config.getIndexed(ITEM_KEY).mapValues { (_, item) -> get() = config.getIndexed(ITEM_KEY).entries.associate { (name, item) ->
if (name == null) error("Child item index should not be null")
val node = item.node ?: error("Node descriptor must be a node") val node = item.node ?: error("Node descriptor must be a node")
if (node[IS_NODE_KEY].boolean == true) { if (node[IS_NODE_KEY].boolean == true) {
NodeDescriptor(node) name to NodeDescriptor(node as Config)
} else { } else {
ValueDescriptor(node) name to ValueDescriptor(node as Config)
} }
} }
@ -112,8 +113,9 @@ public class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config)
get() = config.getIndexed(ITEM_KEY).entries.filter { get() = config.getIndexed(ITEM_KEY).entries.filter {
it.value.node[IS_NODE_KEY].boolean == true it.value.node[IS_NODE_KEY].boolean == true
}.associate { (name, item) -> }.associate { (name, item) ->
if (name == null) error("Child node index should not be null")
val node = item.node ?: error("Node descriptor must be a node") val node = item.node ?: error("Node descriptor must be a node")
name to NodeDescriptor(node) name to NodeDescriptor(node as Config)
} }
/** /**
@ -123,8 +125,9 @@ public class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config)
get() = config.getIndexed(ITEM_KEY).entries.filter { get() = config.getIndexed(ITEM_KEY).entries.filter {
it.value.node[IS_NODE_KEY].boolean != true it.value.node[IS_NODE_KEY].boolean != true
}.associate { (name, item) -> }.associate { (name, item) ->
if (name == null) error("Child value index should not be null")
val node = item.node ?: error("Node descriptor must be a node") val node = item.node ?: error("Node descriptor must be a node")
name to ValueDescriptor(node) name to ValueDescriptor(node as Config)
} }
private fun buildNode(name: Name): NodeDescriptor { private fun buildNode(name: Name): NodeDescriptor {
@ -189,7 +192,8 @@ public class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config)
internal val ITEM_KEY: Name = "item".asName() internal val ITEM_KEY: Name = "item".asName()
internal val IS_NODE_KEY: Name = "@isNode".asName() internal val IS_NODE_KEY: Name = "@isNode".asName()
public inline operator fun invoke(block: NodeDescriptor.() -> Unit): NodeDescriptor = NodeDescriptor().apply(block) public inline operator fun invoke(block: NodeDescriptor.() -> Unit): NodeDescriptor =
NodeDescriptor().apply(block)
//TODO infer descriptor from spec //TODO infer descriptor from spec
} }
@ -270,7 +274,7 @@ public class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config)
val value = it.value val value = it.value
when { when {
value?.list != null -> value.list value?.list != null -> value.list
type?.let { type -> type.size == 1 && type[0] === ValueType.BOOLEAN} ?: false -> listOf(True, False) type?.let { type -> type.size == 1 && type[0] === ValueType.BOOLEAN } ?: false -> listOf(True, False)
else -> emptyList() else -> emptyList()
} }
}, },