Fixed json conversion issue for new Meta structure.
This commit is contained in:
parent
3033cc6304
commit
dd05897759
@ -4,6 +4,7 @@ import com.github.cliftonlabs.json_simple.JsonArray
|
||||
import com.github.cliftonlabs.json_simple.JsonObject
|
||||
import com.github.cliftonlabs.json_simple.Jsoner
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.toName
|
||||
import kotlinx.io.core.*
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.InputStreamReader
|
||||
@ -97,12 +98,18 @@ private fun MetaBuilder.appendValue(key: String, value: Any?) {
|
||||
when (value) {
|
||||
is JsonObject -> this[key] = value.toMeta()
|
||||
is JsonArray -> {
|
||||
value.forEach {
|
||||
if (it is JsonArray) {
|
||||
this[key] = it.toListValue()
|
||||
} else {
|
||||
appendValue(key, it)
|
||||
if (value.none { it is JsonObject }) {
|
||||
//If all values are primitives or arrays
|
||||
this[key] = value.toListValue()
|
||||
} else {
|
||||
val list = value.map<Any, Meta> {
|
||||
when(it){
|
||||
is JsonObject -> it.toMeta()
|
||||
is JsonArray -> it.toListValue().toMeta()
|
||||
else -> Value.of(it).toMeta()
|
||||
}
|
||||
}
|
||||
setIndexed(key.toName(),list)
|
||||
}
|
||||
}
|
||||
is Number -> this[key] = NumberValue(value)
|
||||
|
@ -35,6 +35,8 @@ interface Meta {
|
||||
}
|
||||
}
|
||||
|
||||
/* Get operations*/
|
||||
|
||||
/**
|
||||
* Fast [String]-based accessor for item map
|
||||
*/
|
||||
@ -51,10 +53,22 @@ operator fun Meta.get(name: Name): MetaItem<out Meta>? {
|
||||
}
|
||||
|
||||
operator fun Meta.get(token: NameToken): MetaItem<out Meta>? = items[token]
|
||||
|
||||
//TODO create Java helper for meta operations
|
||||
operator fun Meta.get(key: String): MetaItem<out Meta>? = get(key.toName())
|
||||
|
||||
/**
|
||||
* Get all items matching given name.
|
||||
*/
|
||||
fun Meta.getByName(name: Name): Map<String, MetaItem<out Meta>> {
|
||||
if (name.length == 0) error("Can't use empty name for that")
|
||||
val (body, query) = name.last()!!
|
||||
val regex = query.toRegex()
|
||||
return (this[name.cutLast()] as? NodeItem<*>)?.node?.items
|
||||
?.filter { it.key.body == body && (query.isEmpty()|| regex.matches(it.key.query)) }
|
||||
?.mapKeys { it.key.query }
|
||||
?: emptyMap()
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A meta node that ensures that all of its descendants has at least the same type
|
||||
*/
|
||||
@ -91,6 +105,7 @@ abstract class MetaNode<M : MetaNode<M>> : Meta {
|
||||
* If the argument is possibly mutable node, it is copied on creation
|
||||
*/
|
||||
class SealedMeta internal constructor(override val items: Map<NameToken, MetaItem<SealedMeta>>) : MetaNode<SealedMeta>()
|
||||
|
||||
/**
|
||||
* Generate sealed node from [this]. If it is already sealed return it as is
|
||||
*/
|
||||
@ -133,3 +148,5 @@ val <M : Meta> MetaItem<M>.node: M
|
||||
interface Metoid {
|
||||
val meta: Meta
|
||||
}
|
||||
|
||||
fun Value.toMeta() = buildMeta { Meta.VALUE_KEY to this }
|
@ -54,7 +54,7 @@ abstract class MutableMetaNode<M : MutableMetaNode<M>> : MetaNode<M>(), MutableM
|
||||
oldItem?.node?.removeListener(this)
|
||||
} else {
|
||||
_items[key] = newItem
|
||||
if(newItem is MetaItem.NodeItem) {
|
||||
if (newItem is MetaItem.NodeItem) {
|
||||
newItem.node.onChange(this) { name, oldChild, newChild ->
|
||||
itemChanged(key + name, oldChild, newChild)
|
||||
}
|
||||
@ -105,7 +105,6 @@ operator fun <M : MutableMeta<M>> M.set(name: String, value: Value) = set(name.t
|
||||
operator fun <M : MutableMetaNode<M>> M.set(name: String, meta: Meta) = set(name.toName(), meta)
|
||||
operator fun <M : MutableMeta<M>> M.set(token: NameToken, item: MetaItem<M>?) = set(token.toName(), item)
|
||||
|
||||
|
||||
/**
|
||||
* Universal set method
|
||||
*/
|
||||
@ -134,16 +133,20 @@ fun <M : MutableMetaNode<M>> M.update(meta: Meta) {
|
||||
}
|
||||
}
|
||||
|
||||
// Same name siblings generation
|
||||
/* Same name siblings generation */
|
||||
|
||||
fun <M : MutableMetaNode<M>> M.setIndexed(name: Name, metas: Iterable<Meta>, queryFactory: (Int) -> String = { it.toString() }) {
|
||||
fun <M : MutableMeta<M>> M.setIndexed(name: Name, items: Iterable<MetaItem<M>>, queryFactory: (Int) -> String = { it.toString() }) {
|
||||
val tokens = name.tokens.toMutableList()
|
||||
val last = tokens.last()
|
||||
metas.forEachIndexed { index, meta ->
|
||||
items.forEachIndexed { index, meta ->
|
||||
val indexedToken = NameToken(last.body, last.query + queryFactory(index))
|
||||
tokens[tokens.lastIndex] = indexedToken
|
||||
set(Name(tokens), meta)
|
||||
}
|
||||
}
|
||||
|
||||
fun <M : MutableMetaNode<M>> M.setIndexed(name: Name, metas: Iterable<Meta>, queryFactory: (Int) -> String = { it.toString() }) {
|
||||
setIndexed(name, metas.map { wrap(name, it) }, queryFactory)
|
||||
}
|
||||
|
||||
operator fun <M : MutableMetaNode<M>> M.set(name: Name, metas: Iterable<Meta>) = setIndexed(name, metas)
|
||||
|
@ -22,12 +22,12 @@ class Name internal constructor(val tokens: List<NameToken>) {
|
||||
fun last(): NameToken? = tokens.lastOrNull()
|
||||
|
||||
/**
|
||||
* The reminder of the name after first element is cut
|
||||
* The reminder of the name after first element is cut. For empty name return itself.
|
||||
*/
|
||||
fun cutFirst(): Name = Name(tokens.drop(1))
|
||||
|
||||
/**
|
||||
* The reminder of the name after last element is cut
|
||||
* The reminder of the name after last element is cut. For empty name return itself.
|
||||
*/
|
||||
fun cutLast(): Name = Name(tokens.dropLast(1))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user