Finish migrating to 0.4.0 plugin

This commit is contained in:
Alexander Nozik 2020-03-13 19:15:37 +03:00
parent e2845f4efc
commit db03dfaae9
32 changed files with 235 additions and 243 deletions

View File

@ -1,10 +1,12 @@
import scientifik.coroutines
plugins { plugins {
id("scientifik.mpp") id("scientifik.mpp")
} }
description = "Context and provider definitions" description = "Context and provider definitions"
val coroutinesVersion: String = Scientifik.coroutinesVersion coroutines()
kotlin { kotlin {
sourceSets { sourceSets {
@ -13,20 +15,17 @@ kotlin {
api(project(":dataforge-meta")) api(project(":dataforge-meta"))
api(kotlin("reflect")) api(kotlin("reflect"))
api("io.github.microutils:kotlin-logging-common:1.7.8") api("io.github.microutils:kotlin-logging-common:1.7.8")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion")
} }
} }
val jvmMain by getting { val jvmMain by getting {
dependencies { dependencies {
api("io.github.microutils:kotlin-logging:1.7.8") api("io.github.microutils:kotlin-logging:1.7.8")
api("ch.qos.logback:logback-classic:1.2.3") api("ch.qos.logback:logback-classic:1.2.3")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
} }
} }
val jsMain by getting { val jsMain by getting {
dependencies { dependencies {
api("io.github.microutils:kotlin-logging-js:1.7.8") api("io.github.microutils:kotlin-logging-js:1.7.8")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion")
} }
} }
} }

View File

@ -1,4 +1,5 @@
import scientifik.useSerialization import scientifik.DependencySourceSet.TEST
import scientifik.serialization
plugins { plugins {
id("scientifik.mpp") id("scientifik.mpp")
@ -6,7 +7,9 @@ plugins {
description = "IO module" description = "IO module"
useSerialization() serialization(sourceSet = TEST){
cbor()
}
val ioVersion by rootProject.extra("0.2.0-npm-dev-4") val ioVersion by rootProject.extra("0.2.0-npm-dev-4")
@ -16,17 +19,6 @@ kotlin {
dependencies { dependencies {
api(project(":dataforge-context")) api(project(":dataforge-context"))
api("org.jetbrains.kotlinx:kotlinx-io:$ioVersion") api("org.jetbrains.kotlinx:kotlinx-io:$ioVersion")
//api("org.jetbrains.kotlinx:kotlinx-io-metadata:$ioVersion")
}
}
jvmMain {
dependencies {
//api("org.jetbrains.kotlinx:kotlinx-io-jvm:$ioVersion")
}
}
jsMain {
dependencies {
//api("org.jetbrains.kotlinx:kotlinx-io-js:$ioVersion")
} }
} }
} }

View File

@ -1,4 +1,4 @@
import scientifik.useSerialization import scientifik.serialization
plugins { plugins {
id("scientifik.jvm") id("scientifik.jvm")
@ -6,9 +6,11 @@ plugins {
description = "YAML meta IO" description = "YAML meta IO"
useSerialization() serialization{
yaml()
}
dependencies { dependencies {
api(project(":dataforge-io")) api(project(":dataforge-io"))
api("org.yaml:snakeyaml:1.25") api("org.yaml:snakeyaml:1.26")
} }

View File

@ -21,7 +21,7 @@ class FrontMatterEnvelopeFormat(
var line: String = "" var line: String = ""
var offset = 0u var offset = 0u
do { do {
line = readUtf8Line() ?: error("Input does not contain front matter separator") line = readUtf8Line() //?: error("Input does not contain front matter separator")
offset += line.toUtf8Bytes().size.toUInt() offset += line.toUtf8Bytes().size.toUInt()
} while (!line.startsWith(SEPARATOR)) } while (!line.startsWith(SEPARATOR))
@ -46,7 +46,7 @@ class FrontMatterEnvelopeFormat(
override fun Input.readObject(): Envelope { override fun Input.readObject(): Envelope {
var line: String = "" var line: String = ""
do { do {
line = readUtf8Line() ?: error("Input does not contain front matter separator") line = readUtf8Line() //?: error("Input does not contain front matter separator")
} while (!line.startsWith(SEPARATOR)) } while (!line.startsWith(SEPARATOR))
val readMetaFormat = val readMetaFormat =
@ -89,7 +89,7 @@ class FrontMatterEnvelopeFormat(
override fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat? { override fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat? {
val line = input.readUtf8Line() val line = input.readUtf8Line()
return if (line != null && line.startsWith("---")) { return if (line.startsWith("---")) {
invoke() invoke()
} else { } else {
null null

View File

@ -1,13 +1,12 @@
package hep.dataforge.io.yaml package hep.dataforge.io.yaml
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.io.MetaFormat import hep.dataforge.io.MetaFormat
import hep.dataforge.io.MetaFormatFactory import hep.dataforge.io.MetaFormatFactory
import hep.dataforge.meta.DFExperimental import hep.dataforge.meta.DFExperimental
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.toMap import hep.dataforge.meta.toMap
import hep.dataforge.meta.scheme.toMeta
import hep.dataforge.meta.toMeta import hep.dataforge.meta.toMeta
import kotlinx.io.Input import kotlinx.io.Input
import kotlinx.io.Output import kotlinx.io.Output

View File

@ -3,7 +3,6 @@ package hep.dataforge.io.yaml
import hep.dataforge.io.parse import hep.dataforge.io.parse
import hep.dataforge.io.toString import hep.dataforge.io.toString
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.buildMeta
import hep.dataforge.meta.get import hep.dataforge.meta.get
import hep.dataforge.meta.seal import hep.dataforge.meta.seal
import kotlin.test.Test import kotlin.test.Test
@ -13,7 +12,7 @@ import kotlin.test.assertEquals
class YamlMetaFormatTest { class YamlMetaFormatTest {
@Test @Test
fun testYamlMetaFormat() { fun testYamlMetaFormat() {
val meta = buildMeta { val meta = Meta {
"a" put 22 "a" put 22
"node" put { "node" put {
"b" put "DDD" "b" put "DDD"

View File

@ -1,8 +1,11 @@
package hep.dataforge.io package hep.dataforge.io
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.* import hep.dataforge.meta.setItem
import hep.dataforge.values.* import hep.dataforge.values.*
import kotlinx.io.* import kotlinx.io.*
import kotlinx.io.text.readUtf8String import kotlinx.io.text.readUtf8String
@ -112,7 +115,7 @@ object BinaryMetaFormat : MetaFormat, MetaFormatFactory {
} }
'M' -> { 'M' -> {
val length = readInt() val length = readInt()
val meta = buildMeta { val meta = Meta {
(1..length).forEach { _ -> (1..length).forEach { _ ->
val name = readString() val name = readString()
val item = readMetaItem() val item = readMetaItem()

View File

@ -77,7 +77,7 @@ fun EnvelopeBuilder.multipart(
writeRawString(MULTIPART_DATA_SEPARATOR) writeRawString(MULTIPART_DATA_SEPARATOR)
writeEnvelope(envelope) writeEnvelope(envelope)
meta { meta {
append(INDEX_KEY, buildMeta { append(INDEX_KEY, Meta {
"key" put key "key" put key
"index" put counter "index" put counter
}) })

View File

@ -2,29 +2,20 @@
package hep.dataforge.io package hep.dataforge.io
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.meta.descriptors.ItemDescriptor
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.descriptors.ValueDescriptor
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBase import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.MetaItem import hep.dataforge.meta.node
import hep.dataforge.meta.serialization.toJson import hep.dataforge.meta.toJson
import hep.dataforge.meta.serialization.toMeta import hep.dataforge.meta.toMetaItem
import hep.dataforge.names.NameToken
import hep.dataforge.names.toName
import hep.dataforge.values.*
import kotlinx.io.Input import kotlinx.io.Input
import kotlinx.io.Output import kotlinx.io.Output
import kotlinx.io.text.readUtf8String import kotlinx.io.text.readUtf8String
import kotlinx.io.text.writeUtf8String import kotlinx.io.text.writeUtf8String
import kotlinx.serialization.UnstableDefault import kotlinx.serialization.UnstableDefault
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObjectSerializer
import kotlinx.serialization.json.*
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set
@OptIn(UnstableDefault::class) @OptIn(UnstableDefault::class)
class JsonMetaFormat(private val json: Json = DEFAULT_JSON) : MetaFormat { class JsonMetaFormat(private val json: Json = DEFAULT_JSON) : MetaFormat {
@ -37,11 +28,12 @@ class JsonMetaFormat(private val json: Json = DEFAULT_JSON) : MetaFormat {
override fun Input.readMeta(descriptor: NodeDescriptor?): Meta { override fun Input.readMeta(descriptor: NodeDescriptor?): Meta {
val str = readUtf8String() val str = readUtf8String()
val jsonElement = json.parseJson(str) val jsonElement = json.parseJson(str)
return jsonElement.toMeta() val item = jsonElement.toMetaItem(descriptor)
return item.node ?: Meta.EMPTY
} }
companion object : MetaFormatFactory { companion object : MetaFormatFactory {
val DEFAULT_JSON = Json{prettyPrint = true} val DEFAULT_JSON = Json { prettyPrint = true }
override fun invoke(meta: Meta, context: Context): MetaFormat = default override fun invoke(meta: Meta, context: Context): MetaFormat = default

View File

@ -8,7 +8,6 @@ import kotlinx.io.text.readRawString
import kotlinx.io.text.readUtf8Line import kotlinx.io.text.readUtf8Line
import kotlinx.io.text.writeRawString import kotlinx.io.text.writeRawString
import kotlinx.io.text.writeUtf8String import kotlinx.io.text.writeUtf8String
import kotlinx.serialization.toUtf8Bytes
@ExperimentalIoApi @ExperimentalIoApi
class TaglessEnvelopeFormat( class TaglessEnvelopeFormat(
@ -155,7 +154,7 @@ class TaglessEnvelopeFormat(
} }
do { do {
line = readUtf8Line() ?: return PartialEnvelope(Meta.EMPTY, offset.toUInt(), 0.toULong()) line = readUtf8Line() //?: return PartialEnvelope(Meta.EMPTY, offset.toUInt(), 0.toULong())
offset += line.encodeToByteArray().size.toUInt() offset += line.encodeToByteArray().size.toUInt()
//returning an Envelope without data if end of input is reached //returning an Envelope without data if end of input is reached
} while (!line.startsWith(dataStart)) } while (!line.startsWith(dataStart))

View File

@ -20,7 +20,7 @@ fun MetaFormat.fromBytes(packet: Bytes): Meta {
class MetaFormatTest { class MetaFormatTest {
@Test @Test
fun testBinaryMetaFormat() { fun testBinaryMetaFormat() {
val meta = buildMeta { val meta = Meta {
"a" put 22 "a" put 22
"node" put { "node" put {
"b" put "DDD" "b" put "DDD"
@ -35,7 +35,7 @@ class MetaFormatTest {
@Test @Test
fun testJsonMetaFormat() { fun testJsonMetaFormat() {
val meta = buildMeta { val meta = Meta {
"a" put 22 "a" put 22
"node" put { "node" put {
"b" put "DDD" "b" put "DDD"

View File

@ -1,9 +1,9 @@
package hep.dataforge.io package hep.dataforge.io
import hep.dataforge.io.serialization.MetaItemSerializer import hep.dataforge.meta.Meta
import hep.dataforge.io.serialization.MetaSerializer import hep.dataforge.meta.MetaItem
import hep.dataforge.io.serialization.NameSerializer import hep.dataforge.meta.MetaSerializer
import hep.dataforge.meta.buildMeta import hep.dataforge.names.Name
import hep.dataforge.names.toName import hep.dataforge.names.toName
import kotlinx.serialization.cbor.Cbor import kotlinx.serialization.cbor.Cbor
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
@ -13,7 +13,7 @@ import kotlin.test.assertEquals
class MetaSerializerTest { class MetaSerializerTest {
@Test @Test
fun testMetaSerialization() { fun testMetaSerialization() {
val meta = buildMeta { val meta = Meta {
"a" put 22 "a" put 22
"node" put { "node" put {
"b" put "DDD" "b" put "DDD"
@ -29,7 +29,7 @@ class MetaSerializerTest {
@Test @Test
fun testCborSerialization() { fun testCborSerialization() {
val meta = buildMeta { val meta = Meta {
"a" put 22 "a" put 22
"node" put { "node" put {
"b" put "DDD" "b" put "DDD"
@ -47,13 +47,13 @@ class MetaSerializerTest {
@Test @Test
fun testNameSerialization() { fun testNameSerialization() {
val name = "a.b.c".toName() val name = "a.b.c".toName()
val string = Json.indented.stringify(NameSerializer, name) val string = Json.indented.stringify(Name.serializer(), name)
val restored = Json.plain.parse(NameSerializer, string) val restored = Json.plain.parse(Name.serializer(), string)
assertEquals(restored, name) assertEquals(restored, name)
} }
@Test @Test
fun testMetaItemDescriptor(){ fun testMetaItemDescriptor() {
val descriptor = MetaItemSerializer.descriptor.getElementDescriptor(0) val descriptor = MetaItem.serializer(MetaSerializer).descriptor.getElementDescriptor(0)
} }
} }

View File

@ -1,9 +1,9 @@
import scientifik.useSerialization import scientifik.serialization
plugins { plugins {
id("scientifik.mpp") id("scientifik.mpp")
} }
useSerialization() serialization()
description = "Meta definition and basic operations on meta" description = "Meta definition and basic operations on meta"

View File

@ -1,8 +1,5 @@
package hep.dataforge.meta.serialization package hep.dataforge.meta
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBase
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.descriptors.ItemDescriptor import hep.dataforge.meta.descriptors.ItemDescriptor
import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.descriptors.ValueDescriptor import hep.dataforge.meta.descriptors.ValueDescriptor
@ -52,12 +49,7 @@ fun Meta.toJson(descriptor: NodeDescriptor? = null): JsonObject {
return JsonObject(map) return JsonObject(map)
} }
fun JsonElement.toMeta(descriptor: NodeDescriptor? = null): Meta { fun JsonObject.toMeta(descriptor: NodeDescriptor? = null): Meta = JsonMeta(this, descriptor)
return when (val item = toMetaItem(descriptor)) {
is MetaItem.NodeItem<*> -> item.node
is MetaItem.ValueItem -> item.value.toMeta()
}
}
fun JsonPrimitive.toValue(descriptor: ValueDescriptor?): Value { fun JsonPrimitive.toValue(descriptor: ValueDescriptor?): Value {
return when (this) { return when (this) {
@ -106,7 +98,12 @@ class JsonMeta(val json: JsonObject, val descriptor: NodeDescriptor? = null) : M
this[key] = MetaItem.ValueItem(value.toValue(itemDescriptor as? ValueDescriptor)) as MetaItem<JsonMeta> this[key] = MetaItem.ValueItem(value.toValue(itemDescriptor as? ValueDescriptor)) as MetaItem<JsonMeta>
} }
is JsonObject -> { is JsonObject -> {
this[key] = MetaItem.NodeItem(JsonMeta(value, itemDescriptor as? NodeDescriptor)) this[key] = MetaItem.NodeItem(
JsonMeta(
value,
itemDescriptor as? NodeDescriptor
)
)
} }
is JsonArray -> { is JsonArray -> {
when { when {

View File

@ -3,13 +3,9 @@ package hep.dataforge.meta
import hep.dataforge.meta.Meta.Companion.VALUE_KEY import hep.dataforge.meta.Meta.Companion.VALUE_KEY
import hep.dataforge.meta.MetaItem.NodeItem import hep.dataforge.meta.MetaItem.NodeItem
import hep.dataforge.meta.MetaItem.ValueItem import hep.dataforge.meta.MetaItem.ValueItem
import hep.dataforge.meta.serialization.toJson
import hep.dataforge.names.* import hep.dataforge.names.*
import hep.dataforge.values.EnumValue import hep.dataforge.values.*
import hep.dataforge.values.Null import kotlinx.serialization.*
import hep.dataforge.values.Value
import hep.dataforge.values.boolean
import kotlinx.serialization.Serializable
/** /**
@ -22,11 +18,33 @@ sealed class MetaItem<out M : Meta> {
@Serializable @Serializable
data class ValueItem(val value: Value) : MetaItem<Nothing>() { data class ValueItem(val value: Value) : MetaItem<Nothing>() {
override fun toString(): String = value.toString() override fun toString(): String = value.toString()
@Serializer(ValueItem::class)
companion object : KSerializer<ValueItem> {
override val descriptor: SerialDescriptor get() = ValueSerializer.descriptor
override fun deserialize(decoder: Decoder): ValueItem = ValueItem(ValueSerializer.deserialize(decoder))
override fun serialize(encoder: Encoder, value: ValueItem) {
ValueSerializer.serialize(encoder, value.value)
}
}
} }
@Serializable @Serializable
data class NodeItem<M : Meta>(val node: M) : MetaItem<M>() { data class NodeItem<M : Meta>(val node: M) : MetaItem<M>() {
override fun toString(): String = node.toString() override fun toString(): String = node.toString()
@Serializer(NodeItem::class)
companion object : KSerializer<NodeItem<*>> {
override val descriptor: SerialDescriptor get() = ValueSerializer.descriptor
override fun deserialize(decoder: Decoder): NodeItem<*> = NodeItem(MetaSerializer.deserialize(decoder))
override fun serialize(encoder: Encoder, value: NodeItem<*>) {
MetaSerializer.serialize(encoder, value.node)
}
}
} }
companion object { companion object {
@ -72,6 +90,7 @@ interface Meta : MetaRepr {
companion object { companion object {
const val TYPE = "meta" const val TYPE = "meta"
/** /**
* A key for single value node * A key for single value node
*/ */
@ -101,6 +120,7 @@ operator fun Meta?.get(name: Name): MetaItem<*>? {
} }
operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token) operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token)
/** /**
* Parse [Name] from [key] using full name notation and pass it to [Meta.get] * Parse [Name] from [key] using full name notation and pass it to [Meta.get]
*/ */

View File

@ -0,0 +1,53 @@
package hep.dataforge.meta
import hep.dataforge.names.NameToken
import kotlinx.serialization.*
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.json.JsonInput
import kotlinx.serialization.json.JsonObjectSerializer
import kotlinx.serialization.json.JsonOutput
private class DeserializedMeta(override val items: Map<NameToken, MetaItem<Meta>>) : MetaBase()
/**
* Serialized for meta
*/
@Serializer(Meta::class)
object MetaSerializer : KSerializer<Meta> {
private val mapSerializer = MapSerializer(
NameToken.serializer(),
MetaItem.serializer(MetaSerializer)
)
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
override fun deserialize(decoder: Decoder): Meta {
return if (decoder is JsonInput) {
JsonObjectSerializer.deserialize(decoder).toMeta()
} else {
DeserializedMeta(mapSerializer.deserialize(decoder))
}
}
override fun serialize(encoder: Encoder, value: Meta) {
if (encoder is JsonOutput) {
JsonObjectSerializer.serialize(encoder, value.toJson())
} else {
mapSerializer.serialize(encoder, value.items)
}
}
}
@Serializer(Config::class)
object ConfigSerializer : KSerializer<Config> {
override val descriptor: SerialDescriptor get() = MetaSerializer.descriptor
override fun deserialize(decoder: Decoder): Config {
return MetaSerializer.deserialize(decoder).asConfig()
}
override fun serialize(encoder: Encoder, value: Config) {
MetaSerializer.serialize(encoder, value)
}
}

View File

@ -20,7 +20,7 @@ fun Meta.toMap(descriptor: NodeDescriptor? = null): Map<String, Any?> {
* Convert map of maps to meta * Convert map of maps to meta
*/ */
@DFExperimental @DFExperimental
fun Map<String, Any?>.toMeta(descriptor: NodeDescriptor? = null): Meta = buildMeta { fun Map<String, Any?>.toMeta(descriptor: NodeDescriptor? = null): Meta = Meta {
entries.forEach { (key, value) -> entries.forEach { (key, value) ->
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
when (value) { when (value) {

View File

@ -201,7 +201,7 @@ fun Configurable.doubleArray(vararg doubles: Double, key: Name? = null): ReadWri
fun Configurable.config(key: Name? = null): ReadWriteProperty<Any?, Config?> = fun Configurable.config(key: Name? = null): ReadWriteProperty<Any?, Config?> =
config.node(key) config.node(key)
fun Configurable.node(key: Name? = null): ReadWriteProperty<Any?, Meta?> = item().map( fun Configurable.node(key: Name? = null): ReadWriteProperty<Any?, Meta?> = item(key).map(
reader = { it.node }, reader = { it.node },
writer = { it?.let { MetaItem.NodeItem(it) } } writer = { it?.let { MetaItem.NodeItem(it) } }
) )

View File

@ -39,7 +39,7 @@ open class Scheme() : Configurable, Described, MetaRepr {
*/ */
open val defaultLayer: Meta get() = DefaultLayer(Name.EMPTY) open val defaultLayer: Meta get() = DefaultLayer(Name.EMPTY)
override fun toMeta(): Meta = Laminate(config, defaultLayer) override fun toMeta(): Laminate = Laminate(config, defaultLayer)
private inner class DefaultLayer(val path: Name) : MetaBase() { private inner class DefaultLayer(val path: Name) : MetaBase() {
override val items: Map<NameToken, MetaItem<*>> = override val items: Map<NameToken, MetaItem<*>> =
@ -88,9 +88,3 @@ fun Meta.asScheme() =
MetaScheme(this) MetaScheme(this)
fun <T : Configurable> Meta.toScheme(spec: Specification<T>, block: T.() -> Unit) = spec.wrap(this).apply(block) fun <T : Configurable> Meta.toScheme(spec: Specification<T>, block: T.() -> Unit) = spec.wrap(this).apply(block)
/**
* Create a snapshot laminate
*/
fun Scheme.toMeta(): Laminate =
Laminate(config, defaultLayer)

View File

@ -1,110 +0,0 @@
package hep.dataforge.meta.serialization
import hep.dataforge.meta.*
import hep.dataforge.names.NameToken
import hep.dataforge.values.*
import kotlinx.serialization.*
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.list
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.json.JsonInput
import kotlinx.serialization.json.JsonObjectSerializer
import kotlinx.serialization.json.JsonOutput
@Serializer(Value::class)
@OptIn(InternalSerializationApi::class)
object ValueSerializer : KSerializer<Value> {
// private val valueTypeSerializer = EnumSerializer(ValueType::class)
private val listSerializer by lazy { ValueSerializer.list }
override val descriptor: SerialDescriptor = SerialDescriptor("Value") {
boolean("isList")
enum<ValueType>("valueType")
string("value")
}
private fun Decoder.decodeValue(): Value {
return when (decode(ValueType.serializer())) {
ValueType.NULL -> Null
ValueType.NUMBER -> decodeDouble().asValue() //TODO differentiate?
ValueType.BOOLEAN -> decodeBoolean().asValue()
ValueType.STRING -> decodeString().asValue()
}
}
override fun deserialize(decoder: Decoder): Value {
val isList = decoder.decodeBoolean()
return if (isList) {
listSerializer.deserialize(decoder).asValue()
} else {
decoder.decodeValue()
}
}
private fun Encoder.encodeValue(value: Value) {
encode(ValueType.serializer(), value.type)
when (value.type) {
ValueType.NULL -> {
// do nothing
}
ValueType.NUMBER -> encodeDouble(value.double)
ValueType.BOOLEAN -> encodeBoolean(value.boolean)
ValueType.STRING -> encodeString(value.string)
}
}
override fun serialize(encoder: Encoder, value: Value) {
encoder.encodeBoolean(value.isList())
if (value.isList()) {
listSerializer.serialize(encoder, value.list)
} else {
encoder.encodeValue(value)
}
}
}
private class DeserializedMeta(override val items: Map<NameToken, MetaItem<*>>) : MetaBase()
/**
* Serialized for meta
*/
@Serializer(Meta::class)
object MetaSerializer : KSerializer<Meta> {
private val mapSerializer = MapSerializer(
String.serializer(),
MetaItem.serializer(MetaSerializer)
)
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
override fun deserialize(decoder: Decoder): Meta {
return if (decoder is JsonInput) {
JsonObjectSerializer.deserialize(decoder).toMeta()
} else {
DeserializedMeta(mapSerializer.deserialize(decoder).mapKeys { NameToken(it.key) })
}
}
override fun serialize(encoder: Encoder, value: Meta) {
if (encoder is JsonOutput) {
JsonObjectSerializer.serialize(encoder, value.toJson())
} else {
mapSerializer.serialize(encoder, value.items.mapKeys { it.key.toString() })
}
}
}
@Serializer(Config::class)
object ConfigSerializer : KSerializer<Config> {
override val descriptor: SerialDescriptor = MetaSerializer.descriptor
override fun deserialize(decoder: Decoder): Config {
return MetaSerializer.deserialize(decoder).asConfig()
}
override fun serialize(encoder: Encoder, value: Config) {
MetaSerializer.serialize(encoder, value)
}
}

View File

@ -1,33 +1,36 @@
package hep.dataforge.meta.serialization package hep.dataforge.meta
import hep.dataforge.meta.DFExperimental
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.builtins.DoubleArraySerializer import kotlinx.serialization.builtins.DoubleArraySerializer
import kotlinx.serialization.internal.* import kotlinx.serialization.builtins.serializer
fun SerialDescriptorBuilder.boolean(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = fun SerialDescriptorBuilder.boolean(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, PrimitiveDescriptor(name, PrimitiveKind.BOOLEAN), isOptional = isOptional, annotations = annotations.toList()) element(name, Boolean.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList())
fun SerialDescriptorBuilder.string(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = fun SerialDescriptorBuilder.string(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, PrimitiveDescriptor(name, PrimitiveKind.STRING), isOptional = isOptional, annotations = annotations.toList()) element(name, String.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList())
fun SerialDescriptorBuilder.int(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = fun SerialDescriptorBuilder.int(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, PrimitiveDescriptor(name, PrimitiveKind.INT), isOptional = isOptional, annotations = annotations.toList()) element(name, Int.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList())
fun SerialDescriptorBuilder.double(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = fun SerialDescriptorBuilder.double(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name,PrimitiveDescriptor(name, PrimitiveKind.DOUBLE), isOptional = isOptional, annotations = annotations.toList()) element(name, Double.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList())
fun SerialDescriptorBuilder.float(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = fun SerialDescriptorBuilder.float(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, PrimitiveDescriptor(name, PrimitiveKind.FLOAT), isOptional = isOptional, annotations = annotations.toList()) element(name, Float.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList())
fun SerialDescriptorBuilder.long(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = fun SerialDescriptorBuilder.long(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, PrimitiveDescriptor(name, PrimitiveKind.LONG), isOptional = isOptional, annotations = annotations.toList()) element(name, Long.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList())
fun SerialDescriptorBuilder.doubleArray(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = fun SerialDescriptorBuilder.doubleArray(name: String, isOptional: Boolean = false, vararg annotations: Annotation) =
element(name, DoubleArraySerializer().descriptor, isOptional = isOptional, annotations = annotations.toList()) element(name, DoubleArraySerializer().descriptor, isOptional = isOptional, annotations = annotations.toList())
@OptIn(InternalSerializationApi::class) @OptIn(InternalSerializationApi::class)
inline fun <reified E : Enum<E>> SerialDescriptorBuilder.enum(name: String, isOptional: Boolean = false, vararg annotations: Annotation) { inline fun <reified E : Enum<E>> SerialDescriptorBuilder.enum(
name: String,
isOptional: Boolean = false,
vararg annotations: Annotation
) {
val enumDescriptor = SerialDescriptor(serialName, UnionKind.ENUM_KIND) { val enumDescriptor = SerialDescriptor(serialName, UnionKind.ENUM_KIND) {
enumValues<E>().forEach { enumValues<E>().forEach {
val fqn = "$serialName.${it.name}" val fqn = "$serialName.${it.name}"
@ -38,17 +41,11 @@ inline fun <reified E : Enum<E>> SerialDescriptorBuilder.enum(name: String, isOp
element(name, enumDescriptor, isOptional = isOptional, annotations = annotations.toList()) element(name, enumDescriptor, isOptional = isOptional, annotations = annotations.toList())
} }
//inline fun <reified T : Any> KSerializer<T>.descriptor(
// name: String,
// block: SerialDescriptorBuilder.() -> Unit
//): SerialDescriptor =
// SerialDescriptorBuilder(SerialClassDescImpl(name)).apply(block).build()
@DFExperimental @DFExperimental
inline fun <R> Decoder.decodeStructure( inline fun <R> Decoder.decodeStructure(
desc: SerialDescriptor, desc: SerialDescriptor,
vararg typeParams: KSerializer<*> = emptyArray(), vararg typeParams: KSerializer<*> = emptyArray(),
crossinline block: CompositeDecoder.() -> R crossinline block: CompositeDecoder.() -> R
): R { ): R {
val decoder = beginStructure(desc, *typeParams) val decoder = beginStructure(desc, *typeParams)
val res = decoder.block() val res = decoder.block()
@ -56,6 +53,7 @@ inline fun <R> Decoder.decodeStructure(
return res return res
} }
@DFExperimental
inline fun Encoder.encodeStructure( inline fun Encoder.encodeStructure(
desc: SerialDescriptor, desc: SerialDescriptor,
vararg typeParams: KSerializer<*> = emptyArray(), vararg typeParams: KSerializer<*> = emptyArray(),

View File

@ -53,14 +53,13 @@ class Name(val tokens: List<NameToken>) {
} }
} }
@Serializer(Name::class) @Serializer(Name::class)
companion object: KSerializer<Name> { companion object : KSerializer<Name> {
const val NAME_SEPARATOR = "." const val NAME_SEPARATOR = "."
val EMPTY = Name(emptyList()) val EMPTY = Name(emptyList())
override val descriptor: SerialDescriptor = PrimitiveDescriptor("Name", PrimitiveKind.STRING) override val descriptor: SerialDescriptor = PrimitiveDescriptor("hep.dataforge.names.Name", PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): Name { override fun deserialize(decoder: Decoder): Name {
return decoder.decodeString().toName() return decoder.decodeString().toName()
@ -99,8 +98,8 @@ data class NameToken(val body: String, val index: String = "") {
fun hasIndex() = index.isNotEmpty() fun hasIndex() = index.isNotEmpty()
@Serializer(NameToken::class) @Serializer(NameToken::class)
companion object :KSerializer<NameToken>{ companion object : KSerializer<NameToken> {
override val descriptor: SerialDescriptor = PrimitiveDescriptor("NameToken", PrimitiveKind.STRING) override val descriptor: SerialDescriptor = PrimitiveDescriptor("hep.dataforge.names.NameToken", PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): NameToken { override fun deserialize(decoder: Decoder): NameToken {
return decoder.decodeString().toName().first()!! return decoder.decodeString().toName().first()!!

View File

@ -0,0 +1,59 @@
package hep.dataforge.values
import hep.dataforge.meta.boolean
import hep.dataforge.meta.enum
import hep.dataforge.meta.string
import kotlinx.serialization.*
import kotlinx.serialization.builtins.list
@Serializer(Value::class)
object ValueSerializer : KSerializer<Value> {
private val listSerializer by lazy { ValueSerializer.list }
override val descriptor: SerialDescriptor =
SerialDescriptor("hep.dataforge.values.Value") {
boolean("isList")
enum<ValueType>("valueType")
string("value")
}
private fun Decoder.decodeValue(): Value {
return when (decode(ValueType.serializer())) {
ValueType.NULL -> Null
ValueType.NUMBER -> decodeDouble().asValue() //TODO differentiate?
ValueType.BOOLEAN -> decodeBoolean().asValue()
ValueType.STRING -> decodeString().asValue()
}
}
override fun deserialize(decoder: Decoder): Value {
val isList = decoder.decodeBoolean()
return if (isList) {
listSerializer.deserialize(decoder).asValue()
} else {
decoder.decodeValue()
}
}
private fun Encoder.encodeValue(value: Value) {
encode(ValueType.serializer(), value.type)
when (value.type) {
ValueType.NULL -> {
// do nothing
}
ValueType.NUMBER -> encodeDouble(value.double)
ValueType.BOOLEAN -> encodeBoolean(value.boolean)
ValueType.STRING -> encodeString(value.string)
}
}
override fun serialize(encoder: Encoder, value: Value) {
encoder.encodeBoolean(value.isList())
if (value.isList()) {
listSerializer.serialize(encoder, value.list)
} else {
encoder.encodeValue(value)
}
}
}

View File

@ -11,12 +11,12 @@ class MetaExtensionTest {
@Test @Test
fun testEnum(){ fun testEnum(){
val meta = buildMeta{"enum" put TestEnum.test} val meta = Meta{"enum" put TestEnum.test}
meta["enum"].enum<TestEnum>() meta["enum"].enum<TestEnum>()
} }
@Test @Test
fun testEnumByString(){ fun testEnumByString(){
val meta = buildMeta{"enum" put TestEnum.test.name} val meta = Meta{"enum" put TestEnum.test.name}
println(meta["enum"].enum<TestEnum>()) println(meta["enum"].enum<TestEnum>())
} }

View File

@ -16,13 +16,13 @@ class MetaTest {
@Test @Test
fun metaEqualityTest() { fun metaEqualityTest() {
val meta1 = buildMeta { val meta1 = Meta {
"a" put 22 "a" put 22
"b" put { "b" put {
"c" put "ddd" "c" put "ddd"
} }
} }
val meta2 = buildMeta { val meta2 = Meta {
"b" put { "b" put {
"c" put "ddd" "c" put "ddd"
} }
@ -33,13 +33,13 @@ class MetaTest {
@Test @Test
fun metaToMap(){ fun metaToMap(){
val meta = buildMeta { val meta = Meta {
"a" put 22 "a" put 22
"b" put { "b" put {
"c" put "ddd" "c" put "ddd"
} }
"list" put (0..4).map { "list" put (0..4).map {
buildMeta { Meta {
"value" put it "value" put it
} }
} }

View File

@ -6,7 +6,7 @@ import kotlin.test.assertEquals
class MutableMetaTest{ class MutableMetaTest{
@Test @Test
fun testRemove(){ fun testRemove(){
val meta = buildMeta { val meta = Meta {
"aNode" put { "aNode" put {
"innerNode" put { "innerNode" put {
"innerValue" put true "innerValue" put true

View File

@ -2,7 +2,6 @@ package hep.dataforge.meta
import hep.dataforge.meta.scheme.asScheme import hep.dataforge.meta.scheme.asScheme
import hep.dataforge.meta.scheme.getProperty import hep.dataforge.meta.scheme.getProperty
import hep.dataforge.meta.scheme.toMeta
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -10,7 +9,7 @@ import kotlin.test.assertEquals
class SchemeTest{ class SchemeTest{
@Test @Test
fun testMetaScheme(){ fun testMetaScheme(){
val styled = buildMeta { val styled = Meta {
repeat(10){ repeat(10){
"b.a[$it]" put { "b.a[$it]" put {
"d" put it "d" put it

View File

@ -15,7 +15,7 @@ import kotlinx.io.asBinary
suspend fun Table<Value>.wrap(): Envelope = Envelope { suspend fun Table<Value>.wrap(): Envelope = Envelope {
meta { meta {
header.forEachIndexed { index, columnHeader -> header.forEachIndexed { index, columnHeader ->
set("column", index.toString(), buildMeta { set("column", index.toString(), Meta {
"name" put columnHeader.name "name" put columnHeader.name
if (!columnHeader.meta.isEmpty()) { if (!columnHeader.meta.isEmpty()) {
"meta" put columnHeader.meta "meta" put columnHeader.meta

View File

@ -5,7 +5,6 @@ import hep.dataforge.data.DataNode
import hep.dataforge.data.filter import hep.dataforge.data.filter
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaRepr import hep.dataforge.meta.MetaRepr
import hep.dataforge.meta.buildMeta
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.asName import hep.dataforge.names.asName
import hep.dataforge.names.isEmpty import hep.dataforge.names.isEmpty
@ -28,7 +27,7 @@ class DataDependency(val filter: DataFilter, val placement: Name = Name.EMPTY) :
} }
} }
override fun toMeta(): Meta = buildMeta { override fun toMeta(): Meta = Meta {
"data" put filter.config "data" put filter.config
"to" put placement.toString() "to" put placement.toString()
} }
@ -41,7 +40,7 @@ class AllDataDependency(val placement: Name = Name.EMPTY) : Dependency() {
DataNode.invoke(Any::class) { this[placement] = workspace.data } DataNode.invoke(Any::class) { this[placement] = workspace.data }
} }
override fun toMeta() = buildMeta { override fun toMeta() = Meta {
"data" put "@all" "data" put "@all"
"to" put placement.toString() "to" put placement.toString()
} }
@ -69,7 +68,7 @@ abstract class TaskDependency<out T : Any>(
} }
} }
override fun toMeta(): Meta = buildMeta { override fun toMeta(): Meta = Meta {
"task" put name.toString() "task" put name.toString()
"meta" put meta "meta" put meta
"to" put placement.toString() "to" put placement.toString()

View File

@ -29,7 +29,7 @@ data class TaskModel(
//TODO provide a way to get task descriptor //TODO provide a way to get task descriptor
//TODO add pre-run check of task result type? //TODO add pre-run check of task result type?
override fun toMeta(): Meta = buildMeta { override fun toMeta(): Meta = Meta {
"name" put name.toString() "name" put name.toString()
"meta" put meta "meta" put meta
"dependsOn" put { "dependsOn" put {
@ -98,7 +98,7 @@ fun <T : Any> TaskDependencyContainer.dependsOn(
placement: Name = Name.EMPTY, placement: Name = Name.EMPTY,
metaBuilder: MetaBuilder.() -> Unit metaBuilder: MetaBuilder.() -> Unit
): DirectTaskDependency<T> = ): DirectTaskDependency<T> =
dependsOn(task, placement, buildMeta(metaBuilder)) dependsOn(task, placement, Meta(metaBuilder))
/** /**
* Add custom data dependency * Add custom data dependency

View File

@ -8,7 +8,6 @@ import hep.dataforge.data.DataNode
import hep.dataforge.data.dataSequence import hep.dataforge.data.dataSequence
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.buildMeta
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.provider.Provider import hep.dataforge.provider.Provider
@ -76,7 +75,7 @@ fun Workspace.run(task: String, meta: Meta) =
tasks[task.toName()]?.let { run(it, meta) } ?: error("Task with name $task not found") tasks[task.toName()]?.let { run(it, meta) } ?: error("Task with name $task not found")
fun Workspace.run(task: String, block: MetaBuilder.() -> Unit = {}) = fun Workspace.run(task: String, block: MetaBuilder.() -> Unit = {}) =
run(task, buildMeta(block)) run(task, Meta(block))
fun <T: Any> Workspace.run(task: Task<T>, metaBuilder: MetaBuilder.() -> Unit = {}): DataNode<T> = fun <T: Any> Workspace.run(task: Task<T>, metaBuilder: MetaBuilder.() -> Unit = {}): DataNode<T> =
run(task, buildMeta(metaBuilder)) run(task, Meta(metaBuilder))

View File

@ -52,7 +52,7 @@ fun WorkspaceBuilder.data(
fun WorkspaceBuilder.target(name: String, block: MetaBuilder.() -> Unit) { fun WorkspaceBuilder.target(name: String, block: MetaBuilder.() -> Unit) {
targets[name] = buildMeta(block).seal() targets[name] = Meta(block).seal()
} }
/** /**