Transformation of Meta to Map and back
This commit is contained in:
parent
d3dd15884c
commit
cd4736ab5e
@ -1,9 +0,0 @@
|
||||
plugins {
|
||||
id("scientifik.jvm")
|
||||
}
|
||||
|
||||
description = "YAML meta IO"
|
||||
|
||||
dependencies{
|
||||
api(project(":dataforge-io"))
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package hep.dataforge.meta
|
||||
|
||||
/**
|
||||
* General marker for dataforge builders
|
||||
*/
|
||||
@DslMarker
|
||||
annotation class DFBuilder
|
@ -4,8 +4,6 @@ import hep.dataforge.names.NameToken
|
||||
|
||||
/**
|
||||
* A meta laminate consisting of multiple immutable meta layers. For mutable front layer, use [Styled].
|
||||
*
|
||||
*
|
||||
*/
|
||||
class Laminate(layers: List<Meta>) : MetaBase() {
|
||||
|
||||
|
@ -80,27 +80,6 @@ operator fun Meta?.get(name: Name): MetaItem<*>? {
|
||||
operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token)
|
||||
operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName())
|
||||
|
||||
/**
|
||||
* Get all items matching given name.
|
||||
*/
|
||||
fun Meta.getAll(name: Name): Map<String, MetaItem<*>> {
|
||||
val root = when (name.length) {
|
||||
0 -> error("Can't use empty name for that")
|
||||
1 -> this
|
||||
else -> (this[name.cutLast()] as? NodeItem<*>)?.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()
|
||||
}
|
||||
|
||||
fun Meta.getAll(name: String): Map<String, MetaItem<*>> = getAll(name.toName())
|
||||
|
||||
/**
|
||||
* Get a sequence of [Name]-[Value] pairs
|
||||
*/
|
||||
@ -138,27 +117,6 @@ interface MetaNode<M : MetaNode<M>> : Meta {
|
||||
override val items: Map<NameToken, MetaItem<M>>
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all items matching given name.
|
||||
*/
|
||||
fun <M : MetaNode<M>> M.getAll(name: Name): Map<String, MetaItem<M>> {
|
||||
val root: MetaNode<M>? = when (name.length) {
|
||||
0 -> error("Can't use empty name for that")
|
||||
1 -> this
|
||||
else -> (this[name.cutLast()] as? 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()
|
||||
}
|
||||
|
||||
fun <M : MetaNode<M>> M.getAll(name: String): Map<String, MetaItem<M>> = getAll(name.toName())
|
||||
|
||||
operator fun <M : MetaNode<M>> MetaNode<M>?.get(name: Name): MetaItem<M>? {
|
||||
if (this == null) return null
|
||||
return name.first()?.let { token ->
|
||||
@ -229,7 +187,6 @@ object EmptyMeta : MetaBase() {
|
||||
/**
|
||||
* Unsafe methods to access values and nodes directly from [MetaItem]
|
||||
*/
|
||||
|
||||
val MetaItem<*>?.value: Value?
|
||||
get() = (this as? ValueItem)?.value
|
||||
?: (this?.node?.get(VALUE_KEY) as? ValueItem)?.value
|
||||
@ -258,11 +215,4 @@ val <M : Meta> MetaItem<M>?.node: M?
|
||||
is NodeItem -> node
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic meta-holder object
|
||||
*/
|
||||
interface Metoid {
|
||||
val meta: Meta
|
||||
}
|
||||
|
||||
fun Meta.isEmpty() = this === EmptyMeta || this.items.isEmpty()
|
@ -0,0 +1,11 @@
|
||||
package hep.dataforge.meta
|
||||
|
||||
/**
|
||||
* General marker for dataforge builders
|
||||
*/
|
||||
@DslMarker
|
||||
annotation class DFBuilder
|
||||
|
||||
@Experimental(level = Experimental.Level.WARNING)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class DFExperimental
|
@ -0,0 +1,36 @@
|
||||
package hep.dataforge.meta
|
||||
|
||||
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
|
||||
*/
|
||||
fun Meta.toMap(): Map<String, Any?> {
|
||||
return items.entries.associate { (token, item) ->
|
||||
token.toString() to when (item) {
|
||||
is MetaItem.NodeItem -> item.node.toMap()
|
||||
is MetaItem.ValueItem -> item.value.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert map of maps to meta
|
||||
*/
|
||||
fun Map<String, Any?>.toMeta(): Meta = buildMeta {
|
||||
entries.forEach { (key, value) ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
when (value) {
|
||||
is Map<*, *> -> setNode(key, (value as Map<String, Any?>).toMeta())
|
||||
else -> setValue(key, Value.of(value))
|
||||
}
|
||||
}
|
||||
}
|
@ -28,15 +28,21 @@ class StringDelegate(val meta: Meta, private val key: String? = null, private va
|
||||
}
|
||||
}
|
||||
|
||||
class BooleanDelegate(val meta: Meta, private val key: String? = null, private val default: Boolean? = null) :
|
||||
ReadOnlyProperty<Metoid, Boolean?> {
|
||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Boolean? {
|
||||
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?> {
|
||||
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
|
||||
}
|
||||
@ -168,9 +174,6 @@ fun Meta.number(key: String? = null, default: () -> Number) =
|
||||
inline fun <reified E : Enum<E>> Meta.enum(default: E, key: String? = null) =
|
||||
SafeEnumDelegate(this, key, default) { enumValueOf(it) }
|
||||
|
||||
|
||||
fun <T : Metoid> Metoid.node(key: String? = null, converter: (Meta) -> T) = ChildDelegate(meta, key, converter)
|
||||
|
||||
/* Read-write delegates */
|
||||
|
||||
class MutableValueDelegate<M : MutableMeta<M>>(
|
||||
|
@ -0,0 +1,51 @@
|
||||
package hep.dataforge.meta
|
||||
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
|
||||
/**
|
||||
* Get all items matching given name.
|
||||
*/
|
||||
@DFExperimental
|
||||
fun Meta.getAll(name: Name): Map<String, MetaItem<*>> {
|
||||
val root = when (name.length) {
|
||||
0 -> error("Can't use empty name for that")
|
||||
1 -> this
|
||||
else -> (this[name.cutLast()] as? MetaItem.NodeItem<*>)?.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
|
||||
fun Meta.getAll(name: String): Map<String, MetaItem<*>> = getAll(name.toName())
|
||||
|
||||
|
||||
/**
|
||||
* Get all items matching given name.
|
||||
*/
|
||||
@DFExperimental
|
||||
fun <M : MetaNode<M>> M.getAll(name: Name): Map<String, MetaItem<M>> {
|
||||
val root: MetaNode<M>? = when (name.length) {
|
||||
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
|
||||
fun <M : MetaNode<M>> M.getAll(name: String): Map<String, MetaItem<M>> = getAll(name.toName())
|
@ -30,4 +30,23 @@ class MetaTest {
|
||||
}.seal()
|
||||
assertEquals<Meta>(meta1, meta2)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun metaToMap(){
|
||||
val meta = buildMeta {
|
||||
"a" to 22
|
||||
"b" to {
|
||||
"c" to "ddd"
|
||||
}
|
||||
"list" to (0..4).map {
|
||||
buildMeta {
|
||||
"value" to it
|
||||
}
|
||||
}
|
||||
}
|
||||
val map = meta.toMap()
|
||||
val reconstructed = map.toMeta()
|
||||
|
||||
assertEquals(meta,reconstructed)
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ enableFeaturePreview("GRADLE_METADATA")
|
||||
include(
|
||||
":dataforge-meta",
|
||||
":dataforge-io",
|
||||
":dataforge-io:dataforge-io-yaml",
|
||||
":dataforge-context",
|
||||
":dataforge-data",
|
||||
":dataforge-output",
|
||||
|
Loading…
Reference in New Issue
Block a user