Fixed array representation in DynamicMeta
This commit is contained in:
parent
728da96eff
commit
04e9601def
@ -3,18 +3,27 @@ package hep.dataforge.meta
|
|||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.values.Null
|
import hep.dataforge.values.Null
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
|
import hep.dataforge.values.isList
|
||||||
|
|
||||||
|
|
||||||
//TODO add Meta wrapper for dynamic
|
//TODO add Meta wrapper for dynamic
|
||||||
|
|
||||||
|
fun Value.toDynamic(): dynamic {
|
||||||
|
return if (isList()) {
|
||||||
|
list.map { it.toDynamic() }.toTypedArray().asDynamic()
|
||||||
|
} else {
|
||||||
|
value.asDynamic()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represent or copy this [Meta] to dynamic object to be passed to JS libraries
|
* Represent or copy this [Meta] to dynamic object to be passed to JS libraries
|
||||||
*/
|
*/
|
||||||
fun Meta.toDynamic(): dynamic {
|
fun Meta.toDynamic(): dynamic {
|
||||||
if(this is DynamicMeta) return this.obj
|
if (this is DynamicMeta) return this.obj
|
||||||
|
|
||||||
fun MetaItem<*>.toDynamic(): dynamic = when (this) {
|
fun MetaItem<*>.toDynamic(): dynamic = when (this) {
|
||||||
is MetaItem.ValueItem -> this.value.value.asDynamic()
|
is MetaItem.ValueItem -> this.value.toDynamic()
|
||||||
is MetaItem.NodeItem -> this.node.toDynamic()
|
is MetaItem.NodeItem -> this.node.toDynamic()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,10 +44,15 @@ class DynamicMeta(val obj: dynamic) : MetaBase() {
|
|||||||
private fun isArray(@Suppress("UNUSED_PARAMETER") obj: dynamic): Boolean =
|
private fun isArray(@Suppress("UNUSED_PARAMETER") obj: dynamic): Boolean =
|
||||||
js("Array.isArray(obj)") as Boolean
|
js("Array.isArray(obj)") as Boolean
|
||||||
|
|
||||||
|
private fun isPrimitive(obj: dynamic): Boolean =
|
||||||
|
(jsTypeOf(obj) != "object")
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private fun asItem(obj: dynamic): MetaItem<DynamicMeta>? {
|
private fun asItem(obj: dynamic): MetaItem<DynamicMeta>? {
|
||||||
if (obj == null) return MetaItem.ValueItem(Null)
|
return when {
|
||||||
return when (jsTypeOf(obj as? Any)) {
|
obj == null -> MetaItem.ValueItem(Null)
|
||||||
|
isArray(obj) && (obj as Array<Any?>).all { isPrimitive(it) } -> MetaItem.ValueItem(Value.of(obj as Array<Any?>))
|
||||||
|
else -> when (jsTypeOf(obj)) {
|
||||||
"boolean" -> MetaItem.ValueItem(Value.of(obj as Boolean))
|
"boolean" -> MetaItem.ValueItem(Value.of(obj as Boolean))
|
||||||
"number" -> MetaItem.ValueItem(Value.of(obj as Number))
|
"number" -> MetaItem.ValueItem(Value.of(obj as Number))
|
||||||
"string" -> MetaItem.ValueItem(Value.of(obj as String))
|
"string" -> MetaItem.ValueItem(Value.of(obj as String))
|
||||||
@ -46,16 +60,21 @@ class DynamicMeta(val obj: dynamic) : MetaBase() {
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val items: Map<NameToken, MetaItem<DynamicMeta>>
|
override val items: Map<NameToken, MetaItem<DynamicMeta>>
|
||||||
get() = keys().flatMap<String, Pair<NameToken, MetaItem<DynamicMeta>>> { key ->
|
get() = keys().flatMap<String, Pair<NameToken, MetaItem<DynamicMeta>>> { key ->
|
||||||
val value = obj[key] ?: return@flatMap emptyList()
|
val value = obj[key] ?: return@flatMap emptyList()
|
||||||
if (isArray(value)) {
|
if (isArray(value)) {
|
||||||
return@flatMap (value as Array<dynamic>)
|
val array = value as Array<Any?>
|
||||||
.mapIndexedNotNull() { index, it ->
|
return@flatMap if (array.all { isPrimitive(it) }) {
|
||||||
|
listOf(NameToken(key) to MetaItem.ValueItem(Value.of(array)))
|
||||||
|
} else {
|
||||||
|
array.mapIndexedNotNull { index, it ->
|
||||||
val item = asItem(it) ?: return@mapIndexedNotNull null
|
val item = asItem(it) ?: return@mapIndexedNotNull null
|
||||||
NameToken(key, index.toString()) to item
|
NameToken(key, index.toString()) to item
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
val item = asItem(value) ?: return@flatMap emptyList()
|
val item = asItem(value) ?: return@flatMap emptyList()
|
||||||
listOf(NameToken(key) to item)
|
listOf(NameToken(key) to item)
|
||||||
|
@ -2,6 +2,7 @@ package hep.dataforge.meta
|
|||||||
|
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
|
||||||
class DynamicMetaTest {
|
class DynamicMetaTest {
|
||||||
@ -19,6 +20,34 @@ class DynamicMetaTest {
|
|||||||
val meta = DynamicMeta(d)
|
val meta = DynamicMeta(d)
|
||||||
assertEquals(true, meta["ob.booleanNode"].boolean)
|
assertEquals(true, meta["ob.booleanNode"].boolean)
|
||||||
assertEquals(2, meta["array[1]"].int)
|
assertEquals(2, meta["array[1]"].int)
|
||||||
|
assertEquals(4, meta.items.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testMetaToDynamic(){
|
||||||
|
val meta = buildMeta {
|
||||||
|
"a" to 22
|
||||||
|
"array" to arrayOf(1, 2, 3)
|
||||||
|
"b" to "myString"
|
||||||
|
"ob" to {
|
||||||
|
"childNode" to 18
|
||||||
|
"booleanNode" to true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val dynamic = meta.toDynamic()
|
||||||
|
|
||||||
|
assertEquals(2,dynamic.array[1])
|
||||||
|
|
||||||
|
assertEquals(22, dynamic.a)
|
||||||
|
|
||||||
|
val keys = js("Object.keys(dynamic)") as Array<String>
|
||||||
|
|
||||||
|
assertTrue { keys.contains("ob") }
|
||||||
|
|
||||||
|
assertEquals(18, dynamic.ob.childNode)
|
||||||
|
|
||||||
|
assertEquals<Meta>(meta, DynamicMeta(dynamic))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user