fix dynamic meta

This commit is contained in:
Alexander Nozik 2021-07-30 18:05:57 +03:00
parent b387b21554
commit 5fbbac465a
2 changed files with 15 additions and 8 deletions

View File

@ -1,5 +1,6 @@
package space.kscience.dataforge.meta package space.kscience.dataforge.meta
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.NameToken
import space.kscience.dataforge.values.Value import space.kscience.dataforge.values.Value
import space.kscience.dataforge.values.asValue import space.kscience.dataforge.values.asValue
@ -7,7 +8,7 @@ import space.kscience.dataforge.values.isList
//TODO add Meta wrapper for dynamic //TODO add Meta wrapper for dynamic
@DFExperimental
public fun Value.toDynamic(): dynamic { public fun Value.toDynamic(): dynamic {
return if (isList()) { return if (isList()) {
list.map { it.toDynamic() }.toTypedArray().asDynamic() list.map { it.toDynamic() }.toTypedArray().asDynamic()
@ -19,11 +20,13 @@ public fun Value.toDynamic(): dynamic {
/** /**
* 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
*/ */
@DFExperimental
public fun Meta.toDynamic(): dynamic { public fun Meta.toDynamic(): dynamic {
if (this is DynamicMeta) return this.obj if (this is DynamicMeta) return this.obj
if(items.isEmpty()) return value?.toDynamic()
val res = js("{}") val res = js("{}")
this.items.entries.groupBy { it.key.body }.forEach { (key, value) -> items.entries.groupBy { it.key.body }.forEach { (key, value) ->
val list = value.map { it.value } val list = value.map { it.value }
res[key] = when (list.size) { res[key] = when (list.size) {
1 -> list.first().toDynamic() 1 -> list.first().toDynamic()
@ -33,8 +36,9 @@ public fun Meta.toDynamic(): dynamic {
return res return res
} }
public class DynamicMeta(internal val obj: dynamic) : Meta { @DFExperimental
private fun keys(): Array<String> = js("Object").keys(obj) public class DynamicMeta(internal val obj: dynamic) : TypedMeta<DynamicMeta> {
private fun keys(): Array<String> = js("Object").keys(obj) as Array<String>
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
@ -52,23 +56,25 @@ public class DynamicMeta(internal val obj: dynamic) : Meta {
else -> null else -> null
} }
override val items: Map<NameToken, Meta> override val items: Map<NameToken, DynamicMeta>
get() = if (isPrimitive(obj)) { get() = if (isPrimitive(obj)) {
emptyMap() emptyMap()
} else if (isArray(obj)) { } else if (isArray(obj)) {
if((obj as Array<Any?>).all { isPrimitive(it) }){ if((obj as Array<Any?>).all { isPrimitive(it) }){
emptyMap() emptyMap()
} else{ } else{
TODO() (obj as Array<dynamic>).mapIndexed{ index: Int, b: dynamic ->
val indexString = b[Meta.INDEX_KEY]?.toString() ?: index.toString()
NameToken(Meta.JSON_ARRAY_KEY, indexString) to DynamicMeta(b)
}.toMap()
} }
} else keys().flatMap<String, Pair<NameToken, Meta>> { key -> } else keys().flatMap { key ->
val value = obj[key] ?: return@flatMap emptyList() val value = obj[key] ?: return@flatMap emptyList()
when { when {
isArray(value) -> { isArray(value) -> {
val array = value as Array<Any?> val array = value as Array<Any?>
if (array.all { isPrimitive(it) }) { if (array.all { isPrimitive(it) }) {
//primitive value //primitive value
//emptyList()
listOf(NameToken(key) to DynamicMeta(value)) listOf(NameToken(key) to DynamicMeta(value))
} else { } else {
array.mapIndexedNotNull { index, it -> array.mapIndexedNotNull { index, it ->

View File

@ -39,6 +39,7 @@ class DynamicMetaTest {
} }
val dynamic = meta.toDynamic() val dynamic = meta.toDynamic()
println(JSON.stringify(dynamic))
assertEquals(2,dynamic.array[1]) assertEquals(2,dynamic.array[1])
assertEquals(22, dynamic.a) assertEquals(22, dynamic.a)
val keys = js("Object.keys(dynamic)") as Array<String> val keys = js("Object.keys(dynamic)") as Array<String>