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.
- Context logging moved to the extension
- `number` and `string` methods on `Value` moved to extensions (breaking change)
- \[Major breaking change\] Schemes and configurables us `MutableItemProvider` instead of `Config`
### 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;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;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;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 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 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;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;Ljava/lang/String;)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 static final fun append (Lhep/dataforge/meta/MutableMeta;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;Lhep/dataforge/names/Name;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
}

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())
/**
* Get all items matching given name.
*/
@Suppress("UNCHECKED_CAST")
public fun <M : TypedMeta<M>> M.getIndexed(name: Name): 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>> =
getIndexed(name.toName())
///**
// * Get all items matching given name.
// */
//@Suppress("UNCHECKED_CAST")
//public fun <M : TypedMeta<M>> M.getIndexed(name: Name): 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>> =
// 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 {
items.forEach { (key, item) ->
yield(key.asName() to item)
if (item is NodeItem<*>) {
if (item is NodeItem) {
yieldAll(item.node.itemSequence().map { (innerKey, 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 <M : Meta> M.asMetaItem(): MetaItem.NodeItem<M> = MetaItem.NodeItem(this)
public fun Value.asMetaItem(): ValueItem = ValueItem(this)
public fun <M : Meta> M.asMetaItem(): NodeItem<M> = NodeItem(this)
/**
* Unsafe methods to access values and nodes directly from [MetaItem]
*/
public val MetaItem<*>?.value: Value?
get() = (this as? MetaItem.ValueItem)?.value
?: (this?.node?.get(Meta.VALUE_KEY) as? MetaItem.ValueItem)?.value
get() = (this as? ValueItem)?.value
?: (this?.node?.get(Meta.VALUE_KEY) as? ValueItem)?.value
public val MetaItem<*>?.string: String? get() = value?.string
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?
get() = when (this) {
null -> null
is MetaItem.ValueItem -> null//error("Trying to interpret value meta item as node item")
is MetaItem.NodeItem -> node
is ValueItem -> null//error("Trying to interpret value meta item as node item")
is NodeItem -> node
}

View File

@ -2,6 +2,7 @@ package hep.dataforge.meta
import hep.dataforge.names.*
import hep.dataforge.values.Value
import hep.dataforge.values.asValue
public interface MutableItemProvider : ItemProvider {
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?) {
when (value) {
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 Meta -> set(name, value)
is MetaRepr -> set(name, value.toMeta())
is Configurable -> set(name, value.config)
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:

View File

@ -28,7 +28,7 @@ public abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractTypedMet
//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
is MetaItem.ValueItem -> item
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
*/
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" }
val newIndex = name.lastOrNull()!!.index
if (newIndex != null) {
set(name, value)
} 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)
}
}
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.

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.
*/
@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
@ -40,7 +40,7 @@ public sealed class ItemDescriptor(final override val config: Config): Configura
public abstract fun copy(): ItemDescriptor
public companion object{
public companion object {
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)
*/
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")
if (node[IS_NODE_KEY].boolean == true) {
NodeDescriptor(node)
name to NodeDescriptor(node as Config)
} 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 {
it.value.node[IS_NODE_KEY].boolean == true
}.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")
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 {
it.value.node[IS_NODE_KEY].boolean != true
}.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")
name to ValueDescriptor(node)
name to ValueDescriptor(node as Config)
}
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 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
}
@ -270,7 +274,7 @@ public class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config)
val value = it.value
when {
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()
}
},