diff --git a/.gitignore b/.gitignore index 89cc712a..17a319a4 100644 --- a/.gitignore +++ b/.gitignore @@ -6,5 +6,4 @@ out/ build/ -!gradle-wrapper.jar -gradle.properties \ No newline at end of file +!gradle-wrapper.jar \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..5018fb97 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,39 @@ +# Changelog + +## [Unreleased] +### Added + +### Changed + +### Deprecated + +### Removed + +### Fixed + +### Security +## [0.2.0] +### Added + +### Changed +- Context content resolution refactor +- Kotlin 1.4.10 (build tools 0.6.0) +- Empty query in Name is null instead of "" +- Provider provides an empty map instead of error by default +- Hidden delegates hierarchy in favor of stdlib properties +- Removed io depdendency from `dataforge-output`. Replaced Output by Appendable. +- Configurable is no longer MutableItemProvider. All functionality moved to Scheme. + +### Deprecated +- Context activation API +- TextRenderer + +### Removed +- Functional server prototype +- `dataforge-output` module + +### Fixed +- Global context CoroutineScope resolution +- Library mode compliance + +### Security diff --git a/build.gradle.kts b/build.gradle.kts index ac454902..7d138083 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,27 +1,24 @@ - plugins { - val toolsVersion = "0.5.0" - id("scientifik.mpp") version toolsVersion apply false - id("scientifik.jvm") version toolsVersion apply false - id("scientifik.publish") version toolsVersion apply false - id("org.jetbrains.dokka") version "0.10.1" + id("ru.mipt.npm.project") } -val dataforgeVersion by extra("0.1.8") +val dataforgeVersion by extra("0.2.0") val bintrayRepo by extra("dataforge") val githubProject by extra("dataforge-core") +val spaceRepo by extra("https://maven.jetbrains.space/mipt-npm/p/df/maven") allprojects { group = "hep.dataforge" version = dataforgeVersion + apply<org.jetbrains.dokka.gradle.DokkaPlugin>() + repositories { mavenLocal() } } subprojects { - apply(plugin = "scientifik.publish") - apply(plugin = "org.jetbrains.dokka") + apply(plugin = "ru.mipt.npm.publish") } \ No newline at end of file diff --git a/dataforge-context/api/dataforge-context.api b/dataforge-context/api/dataforge-context.api new file mode 100644 index 00000000..39fa72d8 --- /dev/null +++ b/dataforge-context/api/dataforge-context.api @@ -0,0 +1,334 @@ +public abstract class hep/dataforge/context/AbstractPlugin : hep/dataforge/context/Plugin { + public fun <init> ()V + public fun <init> (Lhep/dataforge/meta/Meta;)V + public synthetic fun <init> (Lhep/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun attach (Lhep/dataforge/context/Context;)V + public fun content (Ljava/lang/String;)Ljava/util/Map; + public synthetic fun dependsOn ()Ljava/util/Collection; + public final fun dependsOn ()Ljava/util/List; + public fun detach ()V + public fun getContext ()Lhep/dataforge/context/Context; + public fun getDefaultChainTarget ()Ljava/lang/String; + public fun getDefaultTarget ()Ljava/lang/String; + public fun getLogger ()Lmu/KLogger; + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getName ()Lhep/dataforge/names/Name; + protected final fun require (Lhep/dataforge/context/PluginFactory;)Lkotlin/properties/ReadOnlyProperty; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/context/AbstractPluginKt { + public static final fun toMap (Ljava/util/Collection;)Ljava/util/Map; +} + +public final class hep/dataforge/context/ClassLoaderPlugin : hep/dataforge/context/AbstractPlugin { + public static final field Companion Lhep/dataforge/context/ClassLoaderPlugin$Companion; + public fun <init> (Ljava/lang/ClassLoader;)V + public fun getTag ()Lhep/dataforge/context/PluginTag; + public final fun services (Lkotlin/reflect/KClass;)Lkotlin/sequences/Sequence; +} + +public final class hep/dataforge/context/ClassLoaderPlugin$Companion { + public final fun getDEFAULT ()Lhep/dataforge/context/ClassLoaderPlugin; +} + +public final class hep/dataforge/context/ClassLoaderPluginKt { + public static final fun getClassLoaderPlugin (Lhep/dataforge/context/Context;)Lhep/dataforge/context/ClassLoaderPlugin; +} + +public class hep/dataforge/context/Context : hep/dataforge/context/Named, hep/dataforge/meta/MetaRepr, hep/dataforge/provider/Provider, kotlinx/coroutines/CoroutineScope { + public static final field Companion Lhep/dataforge/context/Context$Companion; + public static final field PROPERTY_TARGET Ljava/lang/String; + public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/context/Context;Lhep/dataforge/meta/Meta;Ljava/util/Set;)V + public synthetic fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/context/Context;Lhep/dataforge/meta/Meta;Ljava/util/Set;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun close ()V + public fun content (Ljava/lang/String;)Ljava/util/Map; + public final fun content (Ljava/lang/String;Z)Ljava/util/Map; + public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext; + public fun getDefaultChainTarget ()Ljava/lang/String; + public fun getDefaultTarget ()Ljava/lang/String; + public final fun getLogger ()Lmu/KLogger; + public final fun getName ()Lhep/dataforge/names/Name; + public final fun getParent ()Lhep/dataforge/context/Context; + public final fun getPlugins ()Lhep/dataforge/context/PluginManager; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/context/Context$Companion { +} + +public abstract interface class hep/dataforge/context/ContextAware { + public abstract fun getContext ()Lhep/dataforge/context/Context; + public abstract fun getLogger ()Lmu/KLogger; +} + +public final class hep/dataforge/context/ContextAware$DefaultImpls { + public static fun getLogger (Lhep/dataforge/context/ContextAware;)Lmu/KLogger; +} + +public final class hep/dataforge/context/ContextBuilder { + public fun <init> ()V + public fun <init> (Lhep/dataforge/context/Context;Ljava/lang/String;)V + public synthetic fun <init> (Lhep/dataforge/context/Context;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun build ()Lhep/dataforge/context/Context; + public final fun getName ()Ljava/lang/String; + public final fun plugin (Lhep/dataforge/context/Plugin;)V + public final fun plugin (Lhep/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)V + public final fun plugin (Lhep/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;)V + public final fun plugin (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public static synthetic fun plugin$default (Lhep/dataforge/context/ContextBuilder;Lhep/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public static synthetic fun plugin$default (Lhep/dataforge/context/ContextBuilder;Lhep/dataforge/context/PluginTag;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public static synthetic fun plugin$default (Lhep/dataforge/context/ContextBuilder;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public final fun properties (Lkotlin/jvm/functions/Function1;)V + public final fun setName (Ljava/lang/String;)V +} + +public abstract interface class hep/dataforge/context/Factory { + public abstract fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; +} + +public final class hep/dataforge/context/Factory$DefaultImpls { + public static synthetic fun invoke$default (Lhep/dataforge/context/Factory;Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;ILjava/lang/Object;)Ljava/lang/Object; +} + +public final class hep/dataforge/context/Global : hep/dataforge/context/Context { + public static final field INSTANCE Lhep/dataforge/context/Global; + public fun close ()V + public final fun context (Ljava/lang/String;Lhep/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/context/Context; + public static synthetic fun context$default (Lhep/dataforge/context/Global;Ljava/lang/String;Lhep/dataforge/context/Context;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/context/Context; + public final fun getContext (Ljava/lang/String;)Lhep/dataforge/context/Context; + public fun getCoroutineContext ()Lkotlin/coroutines/CoroutineContext; +} + +public abstract interface class hep/dataforge/context/Named { + public static final field Companion Lhep/dataforge/context/Named$Companion; + public abstract fun getName ()Lhep/dataforge/names/Name; +} + +public final class hep/dataforge/context/Named$Companion { + public final fun nameOf (Ljava/lang/Object;)Lhep/dataforge/names/Name; +} + +public final class hep/dataforge/context/NamedKt { + public static final fun isAnonymous (Lhep/dataforge/context/Named;)Z +} + +public abstract interface class hep/dataforge/context/Plugin : hep/dataforge/context/ContextAware, hep/dataforge/context/Named, hep/dataforge/meta/MetaRepr, hep/dataforge/provider/Provider { + public static final field Companion Lhep/dataforge/context/Plugin$Companion; + public static final field TARGET Ljava/lang/String; + public abstract fun attach (Lhep/dataforge/context/Context;)V + public abstract fun dependsOn ()Ljava/util/Collection; + public abstract fun detach ()V + public abstract fun getMeta ()Lhep/dataforge/meta/Meta; + public abstract fun getName ()Lhep/dataforge/names/Name; + public abstract fun getTag ()Lhep/dataforge/context/PluginTag; + public abstract fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/context/Plugin$Companion { + public static final field TARGET Ljava/lang/String; +} + +public final class hep/dataforge/context/Plugin$DefaultImpls { + public static fun content (Lhep/dataforge/context/Plugin;Ljava/lang/String;)Ljava/util/Map; + public static fun getDefaultChainTarget (Lhep/dataforge/context/Plugin;)Ljava/lang/String; + public static fun getDefaultTarget (Lhep/dataforge/context/Plugin;)Ljava/lang/String; + public static fun getLogger (Lhep/dataforge/context/Plugin;)Lmu/KLogger; + public static fun getName (Lhep/dataforge/context/Plugin;)Lhep/dataforge/names/Name; + public static fun toMeta (Lhep/dataforge/context/Plugin;)Lhep/dataforge/meta/Meta; +} + +public abstract interface class hep/dataforge/context/PluginFactory : hep/dataforge/context/Factory { + public static final field Companion Lhep/dataforge/context/PluginFactory$Companion; + public static final field TYPE Ljava/lang/String; + public abstract fun getTag ()Lhep/dataforge/context/PluginTag; + public abstract fun getType ()Lkotlin/reflect/KClass; +} + +public final class hep/dataforge/context/PluginFactory$Companion { + public static final field TYPE Ljava/lang/String; +} + +public final class hep/dataforge/context/PluginManager : hep/dataforge/context/ContextAware, java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker { + public fun <init> (Lhep/dataforge/context/Context;Ljava/util/Set;)V + public final fun fetch (Lhep/dataforge/context/PluginFactory;ZLhep/dataforge/meta/Meta;)Lhep/dataforge/context/Plugin; + public final fun fetch (Lhep/dataforge/context/PluginFactory;ZLkotlin/jvm/functions/Function1;)Lhep/dataforge/context/Plugin; + public static synthetic fun fetch$default (Lhep/dataforge/context/PluginManager;Lhep/dataforge/context/PluginFactory;ZLhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/context/Plugin; + public static synthetic fun fetch$default (Lhep/dataforge/context/PluginManager;Lhep/dataforge/context/PluginFactory;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/context/Plugin; + public final fun find (ZLkotlin/jvm/functions/Function1;)Lhep/dataforge/context/Plugin; + public static synthetic fun find$default (Lhep/dataforge/context/PluginManager;ZLkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/context/Plugin; + public final fun get (Lhep/dataforge/context/PluginTag;Z)Lhep/dataforge/context/Plugin; + public final fun get (Lkotlin/reflect/KClass;Lhep/dataforge/context/PluginTag;Z)Ljava/lang/Object; + public static synthetic fun get$default (Lhep/dataforge/context/PluginManager;Lhep/dataforge/context/PluginTag;ZILjava/lang/Object;)Lhep/dataforge/context/Plugin; + public static synthetic fun get$default (Lhep/dataforge/context/PluginManager;Lkotlin/reflect/KClass;Lhep/dataforge/context/PluginTag;ZILjava/lang/Object;)Ljava/lang/Object; + public fun getContext ()Lhep/dataforge/context/Context; + public fun getLogger ()Lmu/KLogger; + public fun iterator ()Ljava/util/Iterator; + public final fun list (Z)Ljava/util/Collection; + public final fun load (Lhep/dataforge/context/Plugin;)Lhep/dataforge/context/Plugin; + public final fun load (Lhep/dataforge/context/PluginFactory;Lhep/dataforge/meta/Meta;)Lhep/dataforge/context/Plugin; + public final fun load (Lhep/dataforge/context/PluginFactory;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/context/Plugin; + public static synthetic fun load$default (Lhep/dataforge/context/PluginManager;Lhep/dataforge/context/PluginFactory;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/context/Plugin; + public final fun remove (Lhep/dataforge/context/Plugin;)V +} + +public final class hep/dataforge/context/PluginTag : hep/dataforge/meta/MetaRepr { + public static final field Companion Lhep/dataforge/context/PluginTag$Companion; + public static final field DATAFORGE_GROUP Ljava/lang/String; + public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lhep/dataforge/context/PluginTag; + public static synthetic fun copy$default (Lhep/dataforge/context/PluginTag;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lhep/dataforge/context/PluginTag; + public fun equals (Ljava/lang/Object;)Z + public final fun getGroup ()Ljava/lang/String; + public final fun getName ()Ljava/lang/String; + public final fun getVersion ()Ljava/lang/String; + public fun hashCode ()I + public final fun matches (Lhep/dataforge/context/PluginTag;)Z + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/context/PluginTag$Companion { + public final fun fromString (Ljava/lang/String;)Lhep/dataforge/context/PluginTag; +} + +public final class hep/dataforge/context/ResolveKt { + public static final fun gather (Lhep/dataforge/context/Context;Ljava/lang/String;Lkotlin/reflect/KClass;Z)Ljava/util/Map; + public static synthetic fun gather$default (Lhep/dataforge/context/Context;Ljava/lang/String;Lkotlin/reflect/KClass;ZILjava/lang/Object;)Ljava/util/Map; + public static final fun gatherInSequence (Lhep/dataforge/context/Context;Ljava/lang/String;Lkotlin/reflect/KClass;Z)Lkotlin/sequences/Sequence; + public static synthetic fun gatherInSequence$default (Lhep/dataforge/context/Context;Ljava/lang/String;Lkotlin/reflect/KClass;ZILjava/lang/Object;)Lkotlin/sequences/Sequence; + public static final fun getValues (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; + public static final fun resolve (Lhep/dataforge/context/Context;Ljava/lang/String;Lhep/dataforge/names/Name;Lkotlin/reflect/KClass;)Ljava/lang/Object; +} + +public abstract interface annotation class hep/dataforge/descriptors/Attribute : java/lang/annotation/Annotation { + public abstract fun key ()Ljava/lang/String; + public abstract fun value ()Ljava/lang/String; +} + +public abstract interface annotation class hep/dataforge/descriptors/Attributes : java/lang/annotation/Annotation { + public abstract fun attrs ()[Lhep/dataforge/descriptors/Attribute; +} + +public abstract interface annotation class hep/dataforge/descriptors/ItemDef : java/lang/annotation/Annotation { + public abstract fun info ()Ljava/lang/String; + public abstract fun multiple ()Z + public abstract fun required ()Z +} + +public abstract interface annotation class hep/dataforge/descriptors/ValueDef : java/lang/annotation/Annotation { + public abstract fun allowed ()[Ljava/lang/String; + public abstract fun def ()Ljava/lang/String; + public abstract fun enumeration ()Ljava/lang/Class; + public abstract fun type ()[Lhep/dataforge/values/ValueType; +} + +public final class hep/dataforge/properties/ConfigProperty : hep/dataforge/properties/Property { + public fun <init> (Lhep/dataforge/meta/Config;Lhep/dataforge/names/Name;Lhep/dataforge/meta/transformations/MetaConverter;)V + public final fun getConfig ()Lhep/dataforge/meta/Config; + public final fun getConverter ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getName ()Lhep/dataforge/names/Name; + public fun getValue ()Ljava/lang/Object; + public fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V + public fun removeChangeListener (Ljava/lang/Object;)V + public fun setValue (Ljava/lang/Object;)V +} + +public abstract interface class hep/dataforge/properties/Property { + public abstract fun getValue ()Ljava/lang/Object; + public abstract fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V + public abstract fun removeChangeListener (Ljava/lang/Object;)V + public abstract fun setValue (Ljava/lang/Object;)V +} + +public final class hep/dataforge/properties/Property$DefaultImpls { + public static synthetic fun onChange$default (Lhep/dataforge/properties/Property;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public static synthetic fun removeChangeListener$default (Lhep/dataforge/properties/Property;Ljava/lang/Object;ILjava/lang/Object;)V +} + +public final class hep/dataforge/properties/PropertyKt { + public static final fun bind (Lhep/dataforge/properties/Property;Lhep/dataforge/properties/Property;)V + public static final fun mirror (Lhep/dataforge/properties/Property;Lhep/dataforge/properties/Property;Lkotlinx/coroutines/CoroutineScope;)V + public static final fun toFlow (Lhep/dataforge/properties/Property;)Lkotlinx/coroutines/flow/StateFlow; +} + +public final class hep/dataforge/provider/DfTypeKt { + public static final fun getDfType (Lkotlin/reflect/KClass;)Ljava/lang/String; +} + +public final class hep/dataforge/provider/Path : java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker { + public static final field Companion Lhep/dataforge/provider/Path$Companion; + public static final field PATH_SEGMENT_SEPARATOR Ljava/lang/String; + public static final synthetic fun box-impl (Ljava/util/List;)Lhep/dataforge/provider/Path; + public static fun constructor-impl (Ljava/util/List;)Ljava/util/List; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl (Ljava/util/List;Ljava/lang/Object;)Z + public static final fun equals-impl0 (Ljava/util/List;Ljava/util/List;)Z + public static final fun getHead-impl (Ljava/util/List;)Lhep/dataforge/provider/PathToken; + public static final fun getLength-impl (Ljava/util/List;)I + public static final fun getTail-e2ET3QM (Ljava/util/List;)Ljava/util/List; + public final fun getTokens ()Ljava/util/List; + public fun hashCode ()I + public static fun hashCode-impl (Ljava/util/List;)I + public fun iterator ()Ljava/util/Iterator; + public static fun iterator-impl (Ljava/util/List;)Ljava/util/Iterator; + public fun toString ()Ljava/lang/String; + public static fun toString-impl (Ljava/util/List;)Ljava/lang/String; + public final synthetic fun unbox-impl ()Ljava/util/List; +} + +public final class hep/dataforge/provider/Path$Companion { + public final fun parse-IN54j3k (Ljava/lang/String;)Ljava/util/List; +} + +public final class hep/dataforge/provider/PathKt { + public static final fun plus-MQiGgVU (Ljava/util/List;Ljava/util/List;)Ljava/util/List; + public static final fun toPath (Lhep/dataforge/provider/PathToken;)Ljava/util/List; +} + +public final class hep/dataforge/provider/PathToken { + public static final field Companion Lhep/dataforge/provider/PathToken$Companion; + public static final field TARGET_SEPARATOR Ljava/lang/String; + public fun <init> (Lhep/dataforge/names/Name;Ljava/lang/String;)V + public synthetic fun <init> (Lhep/dataforge/names/Name;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lhep/dataforge/names/Name; + public final fun component2 ()Ljava/lang/String; + public final fun copy (Lhep/dataforge/names/Name;Ljava/lang/String;)Lhep/dataforge/provider/PathToken; + public static synthetic fun copy$default (Lhep/dataforge/provider/PathToken;Lhep/dataforge/names/Name;Ljava/lang/String;ILjava/lang/Object;)Lhep/dataforge/provider/PathToken; + public fun equals (Ljava/lang/Object;)Z + public final fun getName ()Lhep/dataforge/names/Name; + public final fun getTarget ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/provider/PathToken$Companion { + public final fun parse (Ljava/lang/String;)Lhep/dataforge/provider/PathToken; +} + +public abstract interface class hep/dataforge/provider/Provider { + public abstract fun content (Ljava/lang/String;)Ljava/util/Map; + public abstract fun getDefaultChainTarget ()Ljava/lang/String; + public abstract fun getDefaultTarget ()Ljava/lang/String; +} + +public final class hep/dataforge/provider/Provider$DefaultImpls { + public static fun content (Lhep/dataforge/provider/Provider;Ljava/lang/String;)Ljava/util/Map; + public static fun getDefaultChainTarget (Lhep/dataforge/provider/Provider;)Ljava/lang/String; + public static fun getDefaultTarget (Lhep/dataforge/provider/Provider;)Ljava/lang/String; +} + +public final class hep/dataforge/provider/ProviderKt { + public static final fun provide-0Dbucg0 (Lhep/dataforge/provider/Provider;Ljava/util/List;Ljava/lang/String;)Ljava/lang/Object; + public static synthetic fun provide-0Dbucg0$default (Lhep/dataforge/provider/Provider;Ljava/util/List;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/Object; + public static final fun top (Lhep/dataforge/provider/Provider;Ljava/lang/String;Lkotlin/reflect/KClass;)Ljava/util/Map; +} + +public abstract interface annotation class hep/dataforge/provider/Type : java/lang/annotation/Annotation { + public abstract fun id ()Ljava/lang/String; +} + diff --git a/dataforge-context/build.gradle.kts b/dataforge-context/build.gradle.kts index c5b41223..01a7e3bb 100644 --- a/dataforge-context/build.gradle.kts +++ b/dataforge-context/build.gradle.kts @@ -1,32 +1,30 @@ -import scientifik.useCoroutines - plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") + id("ru.mipt.npm.native") } description = "Context and provider definitions" - -useCoroutines() +kscience { + useCoroutines() +} kotlin { sourceSets { val commonMain by getting { dependencies { api(project(":dataforge-meta")) - api("io.github.microutils:kotlin-logging-common:1.7.9") + api("io.github.microutils:kotlin-logging:1.9.0-dev-npm-2") } } val jvmMain by getting { dependencies { api(kotlin("reflect")) - api("io.github.microutils:kotlin-logging:1.7.9") api("ch.qos.logback:logback-classic:1.2.3") } } val jsMain by getting { dependencies { - api("io.github.microutils:kotlin-logging-js:1.7.9") } } } diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/AbstractPlugin.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/AbstractPlugin.kt index e1041935..f64c1042 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/AbstractPlugin.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/AbstractPlugin.kt @@ -6,7 +6,7 @@ import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KClass import kotlin.reflect.KProperty -abstract class AbstractPlugin(override val meta: Meta = Meta.EMPTY) : Plugin { +public abstract class AbstractPlugin(override val meta: Meta = Meta.EMPTY) : Plugin { private var _context: Context? = null private val dependencies = ArrayList<PluginFactory<*>>() @@ -30,11 +30,9 @@ abstract class AbstractPlugin(override val meta: Meta = Meta.EMPTY) : Plugin { dependencies.add(factory) return PluginDependencyDelegate(factory.type) } - - override fun provideTop(target: String): Map<Name, Any> = emptyMap() } -fun <T : Named> Collection<T>.toMap(): Map<Name, T> = associate { it.name to it } +public fun <T : Named> Collection<T>.toMap(): Map<Name, T> = associate { it.name to it } private class PluginDependencyDelegate<P : Plugin>(val type: KClass<out P>) : ReadOnlyProperty<AbstractPlugin, P> { override fun getValue(thisRef: AbstractPlugin, property: KProperty<*>): P { diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Context.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Context.kt index bf901991..605e6f8b 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Context.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Context.kt @@ -1,19 +1,18 @@ package hep.dataforge.context -import hep.dataforge.meta.* +import hep.dataforge.meta.Laminate +import hep.dataforge.meta.Meta +import hep.dataforge.meta.MetaRepr +import hep.dataforge.meta.sequence import hep.dataforge.names.Name -import hep.dataforge.names.asName import hep.dataforge.names.plus import hep.dataforge.provider.Provider -import hep.dataforge.provider.top -import hep.dataforge.values.Value import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob import mu.KLogger import mu.KotlinLogging import kotlin.coroutines.CoroutineContext -import kotlin.jvm.JvmName /** * The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top. @@ -24,73 +23,52 @@ import kotlin.jvm.JvmName * different plugins with the same interface in different contexts in the hierarchy. The usual behaviour is to use nearest one, but it could * be overridden by plugin implementation. * - * Since plugins could contain mutable state, context has two states: active and inactive. No changes are allowed to active context. - * @author Alexander Nozik */ -open class Context( +public open class Context( final override val name: Name, - val parent: Context? = Global + public val parent: Context?, + meta: Meta, + plugins: Set<Plugin> = emptySet(), ) : Named, MetaRepr, Provider, CoroutineScope { - private val config = Config() - /** * Context properties. Working as substitute for environment variables */ - val properties: Meta = if (parent == null) { - config + private val properties: Laminate = if (parent == null) { + Laminate(meta) } else { - Laminate(config, parent.properties) + Laminate(meta, parent.properties) } /** * Context logger */ - val logger: KLogger = KotlinLogging.logger(name.toString()) + public val logger: KLogger = KotlinLogging.logger(name.toString()) /** * A [PluginManager] for current context */ - val plugins: PluginManager by lazy { PluginManager(this) } + public val plugins: PluginManager by lazy { PluginManager(this, plugins)} - private val activators = HashSet<Any>() + override val defaultTarget: String get() = Plugin.TARGET - /** - * Defines if context is used in any kind of active computations. Active context properties and plugins could not be changed - */ - val isActive: Boolean = activators.isNotEmpty() - - override val defaultTarget: String get() = Plugin.PLUGIN_TARGET - - override fun provideTop(target: String): Map<Name, Any> { - return when (target) { - Value.TYPE -> properties.sequence().toMap() - Plugin.PLUGIN_TARGET -> plugins.sequence(true).associateBy { it.name } - else -> emptyMap() + public fun content(target: String, inherit: Boolean): Map<Name, Any> { + return if (inherit) { + when (target) { + PROPERTY_TARGET -> properties.sequence().toMap() + Plugin.TARGET -> plugins.list(true).associateBy { it.name } + else -> emptyMap() + } + } else { + when (target) { + PROPERTY_TARGET -> properties.layers.firstOrNull()?.sequence()?.toMap() ?: emptyMap() + Plugin.TARGET -> plugins.list(false).associateBy { it.name } + else -> emptyMap() + } } } - /** - * Mark context as active and used by [activator] - */ - fun activate(activator: Any) { - activators.add(activator) - } - - /** - * Mark context unused by [activator] - */ - fun deactivate(activator: Any) { - activators.remove(activator) - } - - /** - * Change the properties of the context. If active, throw an exception - */ - fun configure(action: Config.() -> Unit) { - if (isActive) error("Can't configure active context") - config.action() - } + override fun content(target: String): Map<Name, Any> = content(target, true) override val coroutineContext: CoroutineContext by lazy { (parent ?: Global).coroutineContext.let { parenContext -> @@ -101,81 +79,35 @@ open class Context( /** * Detach all plugins and terminate context */ - open fun close() { - if (isActive) error("Can't close active context") + public open fun close() { //detach all plugins plugins.forEach { it.detach() } } override fun toMeta(): Meta = Meta { "parent" to parent?.name - "properties" put properties.seal() + "properties" put properties.layers.firstOrNull() "plugins" put plugins.map { it.toMeta() } } -} -fun Context.content(target: String): Map<Name, Any> = content<Any>(target) - -/** - * A map of all objects provided by plugins with given target and type - */ -@JvmName("typedContent") -inline fun <reified T : Any> Context.content(target: String): Map<Name, T> = - plugins.flatMap { plugin -> - plugin.top<T>(target).entries.map { (plugin.name + it.key) to it.value } - }.associate { it } - - -/** - * A global root context. Closing [Global] terminates the framework. - */ -object Global : Context("GLOBAL".asName(), null) { - /** - * Closing all contexts - * - * @throws Exception - */ - override fun close() { - logger.info { "Shutting down GLOBAL" } - for (ctx in contextRegistry.values) { - ctx.close() - } - super.close() + public companion object { + public const val PROPERTY_TARGET: String = "context.property" } - - private val contextRegistry = HashMap<String, Context>() - - /** - * Get previously built context - * - * @param name - * @return - */ - fun getContext(name: String): Context? { - return contextRegistry[name] - } - - fun context(name: String, parent: Context = this, block: ContextBuilder.() -> Unit = {}): Context = - ContextBuilder(name, parent).apply(block).build() - } - /** * The interface for something that encapsulated in context * - * @author Alexander Nozik - * @version $Id: $Id */ -interface ContextAware { +public interface ContextAware { /** * Get context for this object * * @return */ - val context: Context + public val context: Context - val logger: KLogger + public val logger: KLogger get() = if (this is Named) { KotlinLogging.logger((context.name + this.name).toString()) } else { diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/ContextBuilder.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/ContextBuilder.kt index 1f267c37..b742474c 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/ContextBuilder.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/ContextBuilder.kt @@ -1,44 +1,44 @@ package hep.dataforge.context -import hep.dataforge.meta.DFBuilder -import hep.dataforge.meta.Meta -import hep.dataforge.meta.MetaBuilder -import hep.dataforge.meta.buildMeta +import hep.dataforge.meta.* import hep.dataforge.names.toName /** * A convenience builder for context */ @DFBuilder -class ContextBuilder(var name: String = "@anonymous", val parent: Context = Global) { - private val plugins = ArrayList<Plugin>() +public class ContextBuilder(private val parent: Context = Global, public var name: String = "@anonymous") { + private val plugins = HashSet<Plugin>() private var meta = MetaBuilder() - fun properties(action: MetaBuilder.() -> Unit) { + public fun properties(action: MetaBuilder.() -> Unit) { meta.action() } - fun plugin(plugin: Plugin) { + public fun plugin(plugin: Plugin) { plugins.add(plugin) } - fun plugin(tag: PluginTag, action: MetaBuilder.() -> Unit = {}) { - plugins.add(PluginRepository.fetch(tag, Meta(action))) + @OptIn(DFExperimental::class) + private fun findPluginFactory(tag: PluginTag): PluginFactory<*> = + parent.gatherInSequence<PluginFactory<*>>(PluginFactory.TYPE).values + .find { it.tag.matches(tag) } ?: error("Can't resolve plugin factory for $tag") + + public fun plugin(tag: PluginTag, metaBuilder: MetaBuilder.() -> Unit = {}) { + val factory = findPluginFactory(tag) + val plugin = factory.invoke(Meta(metaBuilder), parent) + plugins.add(plugin) } - fun plugin(builder: PluginFactory<*>, action: MetaBuilder.() -> Unit = {}) { + public fun plugin(builder: PluginFactory<*>, action: MetaBuilder.() -> Unit = {}) { plugins.add(builder.invoke(Meta(action))) } - fun plugin(name: String, group: String = "", version: String = "", action: MetaBuilder.() -> Unit = {}) { + public fun plugin(name: String, group: String = "", version: String = "", action: MetaBuilder.() -> Unit = {}) { plugin(PluginTag(name, group, version), action) } - fun build(): Context { - return Context(name.toName(), parent).apply { - this@ContextBuilder.plugins.forEach { - plugins.load(it) - } - } + public fun build(): Context { + return Context(name.toName(), parent, meta.seal(), plugins) } } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Factory.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Factory.kt index b01334e6..b8858a13 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Factory.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Factory.kt @@ -2,6 +2,6 @@ package hep.dataforge.context import hep.dataforge.meta.Meta -interface Factory<out T : Any> { - operator fun invoke(meta: Meta = Meta.EMPTY, context: Context = Global): T +public interface Factory<out T : Any> { + public operator fun invoke(meta: Meta = Meta.EMPTY, context: Context = Global): T } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Global.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Global.kt new file mode 100644 index 00000000..0193ca4b --- /dev/null +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Global.kt @@ -0,0 +1,48 @@ +package hep.dataforge.context + +import hep.dataforge.meta.Meta +import hep.dataforge.names.asName +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.SupervisorJob +import kotlin.coroutines.CoroutineContext +import kotlin.native.concurrent.ThreadLocal + +/** + * A global root context. Closing [Global] terminates the framework. + */ +@ThreadLocal +public object Global : Context("GLOBAL".asName(), null, Meta.EMPTY) { + + override val coroutineContext: CoroutineContext = GlobalScope.coroutineContext + SupervisorJob() + + /** + * Closing all contexts + * + * @throws Exception + */ + override fun close() { + logger.info { "Shutting down GLOBAL" } + for (ctx in contextRegistry.values) { + ctx.close() + } + super.close() + } + + private val contextRegistry = HashMap<String, Context>() + + /** + * Get previously built context + * + * @param name + * @return + */ + public fun getContext(name: String): Context? { + return contextRegistry[name] + } + + public fun context(name: String, parent: Context = this, block: ContextBuilder.() -> Unit = {}): Context = + ContextBuilder(parent, name).apply(block).build().also { + contextRegistry[name] = it + } + +} \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Named.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Named.kt index 9e9db17f..e32946e0 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Named.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Named.kt @@ -24,16 +24,14 @@ import hep.dataforge.names.isEmpty * * @author Alexander Nozik */ -interface Named { +public interface Named { /** * The name of this object instance - * - * @return */ - val name: Name + public val name: Name - companion object { + public companion object { /** * Get the name of given object. If object is Named its name is used, @@ -42,7 +40,7 @@ interface Named { * @param obj * @return */ - fun nameOf(obj: Any): Name { + public fun nameOf(obj: Any): Name { return if (obj is Named) { obj.name } else { @@ -56,5 +54,4 @@ interface Named { * Check if this object has an empty name and therefore is anonymous. * @return */ -val Named.isAnonymous: Boolean - get() = this.name.isEmpty() +public val Named.isAnonymous: Boolean get() = this.name.isEmpty() diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt index 6a937962..ff0e3a0c 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/Plugin.kt @@ -1,43 +1,34 @@ package hep.dataforge.context +import hep.dataforge.context.Plugin.Companion.TARGET import hep.dataforge.meta.Meta import hep.dataforge.meta.MetaRepr -import hep.dataforge.meta.buildMeta import hep.dataforge.names.Name import hep.dataforge.names.toName import hep.dataforge.provider.Provider +import hep.dataforge.provider.Type /** * The interface to define a Context plugin. A plugin stores all runtime features of a context. * The plugin is by default configurable and a Provider (both features could be ignored). * The plugin must in most cases have an empty constructor in order to be able to load it from library. * - * * The plugin lifecycle is the following: * - * * create - configure - attach - detach - destroy - * - * - * Configuration of attached plugin is possible for a context which is not in a runtime mode, but it is not recommended. - * - * @author Alexander Nozik */ -interface Plugin : Named, ContextAware, Provider, MetaRepr { +@Type(TARGET) +public interface Plugin : Named, ContextAware, Provider, MetaRepr { /** * Get tag for this plugin - * - * @return */ - val tag: PluginTag + public val tag: PluginTag - val meta: Meta + public val meta: Meta /** * The name of this plugin ignoring version and group - * - * @return */ override val name: Name get() = tag.name.toName() @@ -45,25 +36,21 @@ interface Plugin : Named, ContextAware, Provider, MetaRepr { * Plugin dependencies which are required to attach this plugin. Plugin * dependencies must be initialized and enabled in the Context before this * plugin is enabled. - * - * @return */ - fun dependsOn(): Collection<PluginFactory<*>> + public fun dependsOn(): Collection<PluginFactory<*>> /** * Start this plugin and attach registration info to the context. This method * should be called only via PluginManager to avoid dependency issues. - * - * @param context */ - fun attach(context: Context) + public fun attach(context: Context) /** * Stop this plugin and remove registration info from context and other * plugins. This method should be called only via PluginManager to avoid * dependency issues. */ - fun detach() + public fun detach() override fun toMeta(): Meta = Meta { "context" put context.name.toString() @@ -72,9 +59,8 @@ interface Plugin : Named, ContextAware, Provider, MetaRepr { "meta" put meta } - companion object { - - const val PLUGIN_TARGET = "plugin" + public companion object { + public const val TARGET: String = "plugin" } } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt index e6e8464e..3e9def85 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginManager.kt @@ -2,42 +2,62 @@ package hep.dataforge.context import hep.dataforge.meta.Meta import hep.dataforge.meta.MetaBuilder +import hep.dataforge.provider.Type import kotlin.reflect.KClass + +@Type(PluginFactory.TYPE) +public interface PluginFactory<T : Plugin> : Factory<T> { + public val tag: PluginTag + public val type: KClass<out T> + + public companion object { + public const val TYPE: String = "pluginFactory" + } +} + /** * The manager for plugin system. Should monitor plugin dependencies and locks. * * @property context A context for this plugin manager * @author Alexander Nozik */ -class PluginManager(override val context: Context) : ContextAware, Iterable<Plugin> { +public class PluginManager(override val context: Context, plugins: Set<Plugin>) : ContextAware, Iterable<Plugin> { + + //TODO refactor to read-only container /** * A set of loaded plugins */ - private val plugins = HashSet<Plugin>() + private val plugins: HashSet<Plugin> = HashSet(plugins) + + init { + plugins.forEach { it.attach(context) } + } /** * A [PluginManager] of parent context if it is present */ private val parent: PluginManager? = context.parent?.plugins - - fun sequence(recursive: Boolean): Sequence<Plugin> { - return if (recursive && parent != null) { - plugins.asSequence() + parent.sequence(true) + /** + * List plugins stored in this [PluginManager]. If [inherit] is true, include parent plugins as well + */ + public fun list(inherit: Boolean): Collection<Plugin> { + return if (inherit && parent != null) { + plugins + parent.list(true) } else { - plugins.asSequence() + plugins } } /** * Get existing plugin or return null if not present. Only first matching plugin is returned. - * @param recursive search for parent [PluginManager] plugins + * @param inherit search for parent [PluginManager] plugins * @param predicate condition for the plugin */ - fun find(recursive: Boolean = true, predicate: (Plugin) -> Boolean): Plugin? = sequence(recursive).find(predicate) - + public fun find(inherit: Boolean = true, predicate: (Plugin) -> Boolean): Plugin? = + list(inherit).find(predicate) /** * Find a loaded plugin via its tag @@ -45,8 +65,8 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug * @param tag * @return */ - operator fun get(tag: PluginTag, recursive: Boolean = true): Plugin? = find(recursive) { tag.matches(it.tag) } - + public operator fun get(tag: PluginTag, inherit: Boolean = true): Plugin? = + find(inherit) { tag.matches(it.tag) } /** * Find a loaded plugin via its class. This method does not check if the result is unique and just returns first @@ -60,13 +80,13 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug * @return */ @Suppress("UNCHECKED_CAST") - operator fun <T : Any> get(type: KClass<out T>, tag: PluginTag? = null, recursive: Boolean = true): T? = + public operator fun <T : Any> get(type: KClass<out T>, tag: PluginTag? = null, recursive: Boolean = true): T? = find(recursive) { type.isInstance(it) && (tag == null || tag.matches(it.tag)) } as T? - inline operator fun <reified T : Any> get(tag: PluginTag? = null, recursive: Boolean = true): T? = + public inline operator fun <reified T : Any> get(tag: PluginTag? = null, recursive: Boolean = true): T? = get(T::class, tag, recursive) - inline operator fun <reified T : Plugin> get(factory: PluginFactory<T>, recursive: Boolean = true): T? = + public inline operator fun <reified T : Plugin> get(factory: PluginFactory<T>, recursive: Boolean = true): T? = get(factory.type, factory.tag, recursive) /** @@ -76,11 +96,9 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug * @param plugin * @return */ - fun <T : Plugin> load(plugin: T): T { - if (context.isActive) error("Can't load plugin into active context") - + public fun <T : Plugin> load(plugin: T): T { if (get(plugin::class, plugin.tag, recursive = false) != null) { - error("Plugin of type ${plugin::class} already exists in ${context.name}") + error("Plugin with tag ${plugin.tag} already exists in ${context.name}") } else { for (tag in plugin.dependsOn()) { fetch(tag, true) @@ -96,18 +114,16 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug /** * Load a plugin using its factory */ - fun <T : Plugin> load(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T = + public fun <T : Plugin> load(factory: PluginFactory<T>, meta: Meta = Meta.EMPTY): T = load(factory(meta, context)) - fun <T : Plugin> load(factory: PluginFactory<T>, metaBuilder: MetaBuilder.() -> Unit): T = + public fun <T : Plugin> load(factory: PluginFactory<T>, metaBuilder: MetaBuilder.() -> Unit): T = load(factory, Meta(metaBuilder)) /** * Remove a plugin from [PluginManager] */ - fun remove(plugin: Plugin) { - if (context.isActive) error("Can't remove plugin from active context") - + public fun remove(plugin: Plugin) { if (plugins.contains(plugin)) { logger.info { "Removing plugin ${plugin.name} from ${context.name}" } plugin.detach() @@ -117,9 +133,8 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug /** * Get an existing plugin with given meta or load new one using provided factory - * */ - fun <T : Plugin> fetch(factory: PluginFactory<T>, recursive: Boolean = true, meta: Meta = Meta.EMPTY): T { + public fun <T : Plugin> fetch(factory: PluginFactory<T>, recursive: Boolean = true, meta: Meta = Meta.EMPTY): T { val loaded = get(factory.type, factory.tag, recursive) return when { loaded == null -> load(factory(meta, context)) @@ -128,10 +143,10 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug } } - fun <T : Plugin> fetch( + public fun <T : Plugin> fetch( factory: PluginFactory<T>, recursive: Boolean = true, - metaBuilder: MetaBuilder.() -> Unit + metaBuilder: MetaBuilder.() -> Unit, ): T = fetch(factory, recursive, Meta(metaBuilder)) override fun iterator(): Iterator<Plugin> = plugins.iterator() diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginRepository.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginRepository.kt deleted file mode 100644 index 248b239c..00000000 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginRepository.kt +++ /dev/null @@ -1,48 +0,0 @@ -package hep.dataforge.context - -import hep.dataforge.meta.Meta -import kotlin.reflect.KClass - -interface PluginFactory<T : Plugin> : Factory<T> { - val tag: PluginTag - val type: KClass<out T> -} - -expect object PluginRepository { - - fun register(factory: PluginFactory<*>) - - /** - * List plugins available in the repository - */ - fun list(): Sequence<PluginFactory<*>> - -} - -/** - * Fetch specific plugin and instantiate it with given meta - */ -fun PluginRepository.fetch(tag: PluginTag, meta: Meta = Meta.EMPTY): Plugin = - list().find { it.tag.matches(tag) }?.invoke(meta = meta) - ?: error("Plugin with tag $tag not found in the repository") - -fun <T : Plugin> PluginRepository.register( - tag: PluginTag, - type: KClass<out T>, - constructor: (Context, Meta) -> T -): PluginFactory<T> { - val factory = object : PluginFactory<T> { - override val tag: PluginTag = tag - override val type: KClass<out T> = type - - override fun invoke(meta: Meta, context: Context): T = constructor(context, meta) - - } - register(factory) - return factory -} - -inline fun <reified T : Plugin> PluginRepository.register(tag: PluginTag, noinline constructor: (Context, Meta) -> T) = - register(tag, T::class, constructor) - -fun PluginRepository.register(plugin: Plugin) = register(plugin.tag, plugin::class) { _, _ -> plugin } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginTag.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginTag.kt index f02308fd..1cd39929 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginTag.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/PluginTag.kt @@ -2,7 +2,6 @@ package hep.dataforge.context import hep.dataforge.meta.Meta import hep.dataforge.meta.MetaRepr -import hep.dataforge.meta.buildMeta /** * The tag which contains information about name, group and version of some @@ -10,7 +9,7 @@ import hep.dataforge.meta.buildMeta * * @author Alexander Nozik */ -data class PluginTag( +public data class PluginTag( val name: String, val group: String = "", val version: String = "" @@ -22,7 +21,7 @@ data class PluginTag( * @param otherTag * @return */ - fun matches(otherTag: PluginTag): Boolean { + public fun matches(otherTag: PluginTag): Boolean { return matchesName(otherTag) && matchesGroup(otherTag) } @@ -42,9 +41,9 @@ data class PluginTag( "version" put version } - companion object { + public companion object { - const val DATAFORGE_GROUP = "hep.dataforge" + public const val DATAFORGE_GROUP: String = "hep.dataforge" /** * Build new PluginTag from standard string representation @@ -52,7 +51,7 @@ data class PluginTag( * @param tag * @return */ - fun fromString(tag: String): PluginTag { + public fun fromString(tag: String): PluginTag { val sepIndex = tag.indexOf(":") return if (sepIndex >= 0) { PluginTag(group = tag.substring(0, sepIndex), name = tag.substring(sepIndex + 1)) diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/resolve.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/resolve.kt new file mode 100644 index 00000000..811220af --- /dev/null +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/context/resolve.kt @@ -0,0 +1,96 @@ +package hep.dataforge.context + +import hep.dataforge.meta.DFExperimental +import hep.dataforge.names.Name +import hep.dataforge.names.plus +import hep.dataforge.provider.Provider +import hep.dataforge.provider.top +import kotlin.reflect.KClass +import kotlin.reflect.cast + +/** + * Resolve a specific element in top level elements of the provider and attempt to cast it to the given type + */ +private fun <T : Any> Provider.provide(target: String, name: Name, type: KClass<out T>): T? { + return content(target)[name]?.let { type.cast(it) } +} + +/** + * Resolve a top level object with given [target] and [name] in a [Context] own scope or its plugins. + */ +public fun <T : Any> Context.resolve(target: String, name: Name, type: KClass<out T>): T? { + //Try searching for plugin an context property + provide(target, name, type)?.let { return it } + val pluginContent = plugins.mapNotNull { it.provide(target, name, type) } + return if (pluginContent.isEmpty()) { + parent?.resolve<T>(target, name, type) + } else { + pluginContent.single() // throws error in case of name/type conflicts + } +} + +/** + * Resolve a top level object with given [target] and [name] in a [Context] own scope or its plugins. + */ +public inline fun <reified T : Any> Context.resolve(target: String, name: Name): T? = + resolve(target, name, T::class) + +/** + * Gather a map of all top-level objects with given [target] from context plugins. + * Content from plugins is prefixed by plugin name so name conflicts are impossible + * This operation could be slow in case of large number of plugins + */ +public fun <T : Any> Context.gather( + target: String, + type: KClass<out T>, + inherit: Boolean = true, +): Map<Name, T> = buildMap { + putAll(top(target, type)) + plugins.forEach { plugin -> + plugin.top(target, type).forEach { (name, value) -> + if (containsKey(name)) error("Name conflict during gather. An item with name $name could not be gathered from $plugin because key is already present.") + put(plugin.name + name, value) + } + } + if (inherit) { + parent?.gather(target, type, inherit)?.forEach { + //put all values from parent if they are not conflicting + if (!containsKey(it.key)) { + put(it.key, it.value) + } + } + } +} + +public inline fun <reified T : Any> Context.gather(target: String, inherit: Boolean = true): Map<Name, T> = + gather(target, T::class, inherit) + +/** + * Gather all content from context itself and its plugins in a form of sequence of name-value pairs. Ignores name conflicts. + * + * Adds parent context sequence as well if [inherit] is true + */ +@DFExperimental +public fun <T : Any> Context.gatherInSequence( + target: String, + type: KClass<out T>, + inherit: Boolean = true, +): Sequence<Map.Entry<Name, T>> = sequence { + yieldAll(top(target, type).entries) + plugins.forEach { plugin -> + yieldAll(plugin.top(target, type).mapKeys { plugin.name + it.key }.entries) + } + if (inherit) { + parent?.gather(target, type, inherit)?.let { + yieldAll(it.entries) + } + } +} + +@DFExperimental +public inline fun <reified T : Any> Context.gatherInSequence( + target: String, + inherit: Boolean = true, +): Sequence<Map.Entry<Name, T>> = gatherInSequence(target, T::class, inherit) + +public val <T> Sequence<Map.Entry<Name, T>>.values: Sequence<T> get() = map { it.value } \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt new file mode 100644 index 00000000..329662b5 --- /dev/null +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt @@ -0,0 +1,33 @@ +package hep.dataforge.properties + +import hep.dataforge.meta.Config +import hep.dataforge.meta.DFExperimental +import hep.dataforge.meta.get +import hep.dataforge.meta.transformations.MetaConverter +import hep.dataforge.meta.transformations.nullableItemToObject +import hep.dataforge.meta.transformations.nullableObjectToMetaItem +import hep.dataforge.names.Name + +@DFExperimental +public class ConfigProperty<T : Any>( + public val config: Config, + public val name: Name, + public val converter: MetaConverter<T>, +) : Property<T?> { + + override var value: T? + get() = converter.nullableItemToObject(config[name]) + set(value) { + config.setItem(name,converter.nullableObjectToMetaItem(value)) + } + + override fun onChange(owner: Any?, callback: (T?) -> Unit) { + config.onChange(owner) { name, oldItem, newItem -> + if (name == this.name && oldItem != newItem) callback(converter.nullableItemToObject(newItem)) + } + } + + override fun removeChangeListener(owner: Any?) { + config.removeListener(owner) + } +} \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/Property.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/Property.kt new file mode 100644 index 00000000..987cfe4c --- /dev/null +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/properties/Property.kt @@ -0,0 +1,48 @@ +package hep.dataforge.properties + +import hep.dataforge.meta.DFExperimental +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow + +@DFExperimental +public interface Property<T> { + public var value: T + + public fun onChange(owner: Any? = null, callback: (T) -> Unit) + public fun removeChangeListener(owner: Any? = null) +} + +@DFExperimental +@OptIn(ExperimentalCoroutinesApi::class) +public fun <T> Property<T>.toFlow(): StateFlow<T> = MutableStateFlow(value).also { stateFlow -> + onChange { + stateFlow.value = it + } +} + +/** + * Reflect all changes in the [source] property onto this property + * + * @return a mirroring job + */ +@DFExperimental +public fun <T> Property<T>.mirror(source: Property<T>, scope: CoroutineScope) { + source.onChange(this) { + this.value = it + } +} + +/** + * Bi-directional connection between properties + */ +@DFExperimental +public fun <T> Property<T>.bind(other: Property<T>) { + onChange(other) { + other.value = it + } + other.onChange { + this.value = it + } +} \ No newline at end of file diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Path.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Path.kt index 06c36ab0..6cd0d7fa 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Path.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Path.kt @@ -26,25 +26,25 @@ import hep.dataforge.names.toName * @author Alexander Nozik * @version $Id: $Id */ -inline class Path(val tokens: List<PathToken>) : Iterable<PathToken> { +public inline class Path(public val tokens: List<PathToken>) : Iterable<PathToken> { - val head: PathToken? get() = tokens.firstOrNull() + public val head: PathToken? get() = tokens.firstOrNull() - val length: Int get() = tokens.size + public val length: Int get() = tokens.size /** * Returns non-empty optional containing the chain without first segment in case of chain path. * * @return */ - val tail: Path? get() = if (tokens.isEmpty()) null else Path(tokens.drop(1)) + public val tail: Path? get() = if (tokens.isEmpty()) null else Path(tokens.drop(1)) override fun iterator(): Iterator<PathToken> = tokens.iterator() - companion object { - const val PATH_SEGMENT_SEPARATOR = "/" + public companion object { + public const val PATH_SEGMENT_SEPARATOR: String = "/" - fun parse(path: String): Path { + public fun parse(path: String): Path { val head = path.substringBefore(PATH_SEGMENT_SEPARATOR) val tail = path.substringAfter(PATH_SEGMENT_SEPARATOR) return PathToken.parse(head).toPath() + parse(tail) @@ -52,18 +52,18 @@ inline class Path(val tokens: List<PathToken>) : Iterable<PathToken> { } } -operator fun Path.plus(path: Path) = Path(this.tokens + path.tokens) +public operator fun Path.plus(path: Path): Path = Path(this.tokens + path.tokens) -data class PathToken(val name: Name, val target: String? = null) { +public data class PathToken(val name: Name, val target: String? = null) { override fun toString(): String = if (target == null) { name.toString() } else { "$target$TARGET_SEPARATOR$name" } - companion object { - const val TARGET_SEPARATOR = "::" - fun parse(token: String): PathToken { + public companion object { + public const val TARGET_SEPARATOR: String = "::" + public fun parse(token: String): PathToken { val target = token.substringBefore(TARGET_SEPARATOR, "") val name = token.substringAfter(TARGET_SEPARATOR).toName() if (target.contains("[")) TODO("target separators in queries are not supported") @@ -72,4 +72,4 @@ data class PathToken(val name: Name, val target: String? = null) { } } -fun PathToken.toPath() = Path(listOf(this)) +public fun PathToken.toPath(): Path = Path(listOf(this)) diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Provider.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Provider.kt index b1d769e2..3a153d86 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Provider.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Provider.kt @@ -16,41 +16,37 @@ package hep.dataforge.provider import hep.dataforge.names.Name -import hep.dataforge.names.toName +import kotlin.reflect.KClass +import kotlin.reflect.safeCast /** * A marker utility interface for providers. * * @author Alexander Nozik */ -interface Provider { +public interface Provider { /** * Default target for this provider - * - * @return */ - val defaultTarget: String get() = "" + public val defaultTarget: String get() = "" /** * Default target for next chain segment - * - * @return */ - val defaultChainTarget: String get() = "" - + public val defaultChainTarget: String get() = "" /** * A map of direct children for specific target */ - fun provideTop(target: String): Map<Name, Any> + public fun content(target: String): Map<Name, Any> = emptyMap() } -fun Provider.provide(path: Path, targetOverride: String? = null): Any? { +public fun Provider.provide(path: Path, targetOverride: String? = null): Any? { if (path.length == 0) throw IllegalArgumentException("Can't provide by empty path") val first = path.first() val target = targetOverride ?: first.target ?: defaultTarget - val res = provideTop(target)[first.name] ?: return null + val res = content(target)[first.name] ?: return null return when (path.length) { 1 -> res else -> { @@ -65,24 +61,29 @@ fun Provider.provide(path: Path, targetOverride: String? = null): Any? { /** * Type checked provide */ -inline fun <reified T : Any> Provider.provide(path: String): T? { - return provide(Path.parse(path)) as? T +public inline fun <reified T : Any> Provider.provide(path: String, targetOverride: String? = null): T? { + return provide(Path.parse(path), targetOverride) as? T } +// +//inline fun <reified T : Any> Provider.provide(target: String, name: Name): T? { +// return provide(PathToken(name, target).toPath()) as? T +//} -inline fun <reified T : Any> Provider.provide(target: String, name: Name): T? { - return provide(PathToken(name, target).toPath()) as? T -} - -inline fun <reified T : Any> Provider.provide(target: String, name: String): T? = - provide(target, name.toName()) +//inline fun <reified T : Any> Provider.provide(target: String, name: String): T? = +// provide(target, name.toName()) /** * Typed top level content */ -inline fun <reified T : Any> Provider.top(target: String): Map<Name, T> { - return provideTop(target).mapValues { - it.value as? T ?: error("The type of element $it is ${it::class} but ${T::class} is expected") +public fun <T : Any> Provider.top(target: String, type: KClass<out T>): Map<Name, T> { + return content(target).mapValues { + type.safeCast(it.value) ?: error("The type of element $it is ${it::class} but $type is expected") } } +/** + * Typed top level content + */ +public inline fun <reified T : Any> Provider.top(target: String): Map<Name, T> = top(target, T::class) + diff --git a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Type.kt b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Type.kt index a31f1fdb..e07cfd10 100644 --- a/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Type.kt +++ b/dataforge-context/src/commonMain/kotlin/hep/dataforge/provider/Type.kt @@ -7,4 +7,4 @@ package hep.dataforge.provider */ @MustBeDocumented @Target(AnnotationTarget.CLASS) -annotation class Type(val id: String) +public annotation class Type(val id: String) diff --git a/dataforge-context/src/commonTest/kotlin/hep/dataforge/context/ContextTest.kt b/dataforge-context/src/commonTest/kotlin/hep/dataforge/context/ContextTest.kt index 584e500c..58647400 100644 --- a/dataforge-context/src/commonTest/kotlin/hep/dataforge/context/ContextTest.kt +++ b/dataforge-context/src/commonTest/kotlin/hep/dataforge/context/ContextTest.kt @@ -11,7 +11,7 @@ class ContextTest { class DummyPlugin : AbstractPlugin() { override val tag get() = PluginTag("test") - override fun provideTop(target: String): Map<Name, Any> { + override fun content(target: String): Map<Name, Any> { return when(target){ "test" -> listOf("a", "b", "c.d").associate { it.toName() to it.toName() } else -> emptyMap() @@ -21,8 +21,11 @@ class ContextTest { @Test fun testPluginManager() { - Global.plugins.load(DummyPlugin()) - val members = Global.content<Name>("test") + val context = Global.context("test"){ + plugin(DummyPlugin()) + } + //Global.plugins.load(DummyPlugin()) + val members = context.gather<Name>("test") assertEquals(3, members.count()) members.forEach { assertEquals(it.key, it.value.appendLeft("test")) diff --git a/dataforge-context/src/jsMain/kotlin/hep/dataforge/context/PluginRepository.kt b/dataforge-context/src/jsMain/kotlin/hep/dataforge/context/PluginRepository.kt deleted file mode 100644 index 78a2952e..00000000 --- a/dataforge-context/src/jsMain/kotlin/hep/dataforge/context/PluginRepository.kt +++ /dev/null @@ -1,16 +0,0 @@ -package hep.dataforge.context - - -actual object PluginRepository { - - private val factories: MutableSet<PluginFactory<*>> = HashSet() - - actual fun register(factory: PluginFactory<*>) { - factories.add(factory) - } - - /** - * List plugins available in the repository - */ - actual fun list(): Sequence<PluginFactory<*>> = factories.asSequence() -} \ No newline at end of file diff --git a/dataforge-context/src/jsMain/kotlin/hep/dataforge/properties/bindings.kt b/dataforge-context/src/jsMain/kotlin/hep/dataforge/properties/bindings.kt new file mode 100644 index 00000000..05818cae --- /dev/null +++ b/dataforge-context/src/jsMain/kotlin/hep/dataforge/properties/bindings.kt @@ -0,0 +1,32 @@ +package hep.dataforge.properties + +import hep.dataforge.meta.DFExperimental +import org.w3c.dom.HTMLInputElement + +@DFExperimental +fun HTMLInputElement.bindValue(property: Property<String>) { + if (this.onchange != null) error("Input element already bound") + this.onchange = { + property.value = this.value + Unit + } + property.onChange(this) { + if (value != it) { + value = it + } + } +} + +@DFExperimental +fun HTMLInputElement.bindChecked(property: Property<Boolean>) { + if (this.onchange != null) error("Input element already bound") + this.onchange = { + property.value = this.checked + Unit + } + property.onChange(this) { + if (checked != it) { + checked = it + } + } +} \ No newline at end of file diff --git a/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/ClassLoaderPlugin.kt b/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/ClassLoaderPlugin.kt index 6d401613..a1e0e6e6 100644 --- a/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/ClassLoaderPlugin.kt +++ b/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/ClassLoaderPlugin.kt @@ -19,24 +19,24 @@ import java.util.* import kotlin.reflect.KClass import kotlin.reflect.full.cast -class ClassLoaderPlugin(val classLoader: ClassLoader) : AbstractPlugin() { +public class ClassLoaderPlugin(private val classLoader: ClassLoader) : AbstractPlugin() { override val tag: PluginTag = PluginTag("classLoader", PluginTag.DATAFORGE_GROUP) private val serviceCache: MutableMap<Class<*>, ServiceLoader<*>> = HashMap() - fun <T : Any> services(type: KClass<T>): Sequence<T> { + public fun <T : Any> services(type: KClass<T>): Sequence<T> { return serviceCache.getOrPut(type.java) { ServiceLoader.load(type.java, classLoader) }.asSequence() .map { type.cast(it) } } - companion object { - val DEFAULT = ClassLoaderPlugin(Global::class.java.classLoader) + public companion object { + public val DEFAULT: ClassLoaderPlugin = ClassLoaderPlugin(Global::class.java.classLoader) } } -val Context.classLoaderPlugin get() = this.plugins.get() ?: ClassLoaderPlugin.DEFAULT +public val Context.classLoaderPlugin: ClassLoaderPlugin get() = this.plugins.get() ?: ClassLoaderPlugin.DEFAULT -inline fun <reified T : Any> Context.services() = classLoaderPlugin.services(T::class) +public inline fun <reified T : Any> Context.services(): Sequence<T> = classLoaderPlugin.services(T::class) //open class JVMContext( diff --git a/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/PluginRepository.kt b/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/PluginRepository.kt deleted file mode 100644 index 83455fd6..00000000 --- a/dataforge-context/src/jvmMain/kotlin/hep/dataforge/context/PluginRepository.kt +++ /dev/null @@ -1,17 +0,0 @@ -package hep.dataforge.context - -actual object PluginRepository { - - private val factories: MutableSet<PluginFactory<*>> = HashSet() - - actual fun register(factory: PluginFactory<*>) { - factories.add(factory) - } - - /** - * List plugins available in the repository - */ - actual fun list(): Sequence<PluginFactory<*>> = - factories.asSequence() + Global.services() - -} \ No newline at end of file diff --git a/dataforge-context/src/jvmMain/kotlin/hep/dataforge/provider/Types.kt b/dataforge-context/src/jvmMain/kotlin/hep/dataforge/provider/Types.kt deleted file mode 100644 index dfe81ce0..00000000 --- a/dataforge-context/src/jvmMain/kotlin/hep/dataforge/provider/Types.kt +++ /dev/null @@ -1,44 +0,0 @@ -package hep.dataforge.provider - -import hep.dataforge.context.Context -import hep.dataforge.context.content -import hep.dataforge.names.Name -import kotlin.reflect.KClass -import kotlin.reflect.full.findAnnotation - -/** - * - */ -object Types { - operator fun get(cl: KClass<*>): String { - return cl.findAnnotation<Type>()?.id ?: cl.simpleName ?: "" - } - - operator fun get(obj: Any): String { - return get(obj::class) - } -} - -/** - * Provide an object with given name inferring target from its type using [Type] annotation - */ -inline fun <reified T : Any> Provider.provideByType(name: String): T? { - val target = Types[T::class] - return provide(target, name) -} - -inline fun <reified T : Any> Provider.provideByType(name: Name): T? { - val target = Types[T::class] - return provide(target, name) -} - -inline fun <reified T : Any> Provider.top(): Map<Name, T> { - val target = Types[T::class] - return top(target) -} - -/** - * A sequences of all objects provided by plugins with given target and type - */ -inline fun <reified T : Any> Context.content(): Map<Name, T> = content<T>(Types[T::class]) - diff --git a/dataforge-context/src/jvmMain/kotlin/hep/dataforge/provider/dfType.kt b/dataforge-context/src/jvmMain/kotlin/hep/dataforge/provider/dfType.kt new file mode 100644 index 00000000..9c08d6a8 --- /dev/null +++ b/dataforge-context/src/jvmMain/kotlin/hep/dataforge/provider/dfType.kt @@ -0,0 +1,36 @@ +package hep.dataforge.provider + +import hep.dataforge.context.Context +import hep.dataforge.context.gather +import hep.dataforge.meta.DFExperimental +import hep.dataforge.names.Name +import kotlin.reflect.KClass +import kotlin.reflect.full.findAnnotation + + +@DFExperimental +public val KClass<*>.dfType: String + get() = findAnnotation<Type>()?.id ?: simpleName ?: "" + +/** + * Provide an object with given name inferring target from its type using [Type] annotation + */ +@DFExperimental +public inline fun <reified T : Any> Provider.provideByType(name: String): T? { + val target = T::class.dfType + return provide(target, name) +} + +@DFExperimental +public inline fun <reified T : Any> Provider.top(): Map<Name, T> { + val target = T::class.dfType + return top(target) +} + +/** + * All objects provided by plugins with given target and type + */ +@DFExperimental +public inline fun <reified T : Any> Context.gather(inherit: Boolean = true): Map<Name, T> = + gather<T>(T::class.dfType, inherit) + diff --git a/dataforge-data/api/dataforge-data.api b/dataforge-data/api/dataforge-data.api new file mode 100644 index 00000000..06e99242 --- /dev/null +++ b/dataforge-data/api/dataforge-data.api @@ -0,0 +1,400 @@ +public abstract interface class hep/dataforge/data/Action { + public abstract fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode; + public abstract fun isTerminal ()Z +} + +public final class hep/dataforge/data/Action$DefaultImpls { + public static fun isTerminal (Lhep/dataforge/data/Action;)Z +} + +public final class hep/dataforge/data/ActionEnv { + public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/Meta;)V + public final fun component1 ()Lhep/dataforge/names/Name; + public final fun component2 ()Lhep/dataforge/meta/Meta; + public final fun component3 ()Lhep/dataforge/meta/Meta; + public final fun copy (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/ActionEnv; + public static synthetic fun copy$default (Lhep/dataforge/data/ActionEnv;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/data/ActionEnv; + public fun equals (Ljava/lang/Object;)Z + public final fun getActionMeta ()Lhep/dataforge/meta/Meta; + public final fun getMeta ()Lhep/dataforge/meta/Meta; + public final fun getName ()Lhep/dataforge/names/Name; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/data/ActionKt { + public static final fun then (Lhep/dataforge/data/Action;Lhep/dataforge/data/Action;)Lhep/dataforge/data/Action; +} + +public final class hep/dataforge/data/CoroutineMonitor : kotlin/coroutines/CoroutineContext$Element { + public static final field Companion Lhep/dataforge/data/CoroutineMonitor$Companion; + public fun <init> ()V + public final fun finish ()V + public fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; + public fun get (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element; + public fun getKey ()Lkotlin/coroutines/CoroutineContext$Key; + public final fun getStatus ()Ljava/lang/String; + public final fun getTotalWork ()D + public final fun getWorkDone ()D + public fun minusKey (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext; + public fun plus (Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext; + public final fun setStatus (Ljava/lang/String;)V + public final fun setTotalWork (D)V + public final fun setWorkDone (D)V + public final fun start ()V +} + +public final class hep/dataforge/data/CoroutineMonitor$Companion : kotlin/coroutines/CoroutineContext$Key { +} + +public final class hep/dataforge/data/CoroutineMonitorKt { + public static final fun getDependencies (Lkotlinx/coroutines/Job;)Ljava/util/Collection; + public static final fun getMonitor (Lkotlin/coroutines/CoroutineContext;)Lhep/dataforge/data/CoroutineMonitor; + public static final fun getMonitor (Lkotlinx/coroutines/CoroutineScope;)Lhep/dataforge/data/CoroutineMonitor; + public static final fun getProgress (Lkotlinx/coroutines/Job;)D + public static final fun getStatus (Lkotlinx/coroutines/Job;)Ljava/lang/String; + public static final fun getTotalWork (Lkotlinx/coroutines/Job;)D + public static final fun getWorkDone (Lkotlinx/coroutines/Job;)D +} + +public abstract interface class hep/dataforge/data/Data : hep/dataforge/data/Goal, hep/dataforge/meta/MetaRepr { + public static final field Companion Lhep/dataforge/data/Data$Companion; + public static final field TYPE Ljava/lang/String; + public abstract fun getMeta ()Lhep/dataforge/meta/Meta; + public abstract fun getType ()Lkotlin/reflect/KClass; + public abstract fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/data/Data$Companion { + public static final field TYPE Ljava/lang/String; + public final fun invoke (Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)Lhep/dataforge/data/Data; + public final fun invoke (Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)Lhep/dataforge/data/Data; + public static synthetic fun invoke$default (Lhep/dataforge/data/Data$Companion;Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lhep/dataforge/data/Data; + public static synthetic fun invoke$default (Lhep/dataforge/data/Data$Companion;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lhep/dataforge/data/Data; + public final fun static (Ljava/lang/Object;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/Data; + public static synthetic fun static$default (Lhep/dataforge/data/Data$Companion;Ljava/lang/Object;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/data/Data; +} + +public final class hep/dataforge/data/Data$DefaultImpls { + public static fun toMeta (Lhep/dataforge/data/Data;)Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/data/DataCastKt { + public static final fun canCast (Lhep/dataforge/data/DataItem;Lkotlin/reflect/KClass;)Z + public static final fun cast (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data; + public static final fun cast (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataNode; + public static final fun ensureType (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)V + public static final fun upcast (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data; +} + +public final class hep/dataforge/data/DataFilter : hep/dataforge/meta/Scheme { + public static final field Companion Lhep/dataforge/data/DataFilter$Companion; + public fun <init> ()V + public final fun getFrom ()Ljava/lang/String; + public final fun getPattern ()Ljava/lang/String; + public final fun getTo ()Ljava/lang/String; + public final fun setFrom (Ljava/lang/String;)V + public final fun setPattern (Ljava/lang/String;)V + public final fun setTo (Ljava/lang/String;)V +} + +public final class hep/dataforge/data/DataFilter$Companion : hep/dataforge/meta/SchemeSpec { +} + +public final class hep/dataforge/data/DataFilterKt { + public static final fun filter (Lhep/dataforge/data/DataNode;Lhep/dataforge/data/DataFilter;)Lhep/dataforge/data/DataNode; + public static final fun filter (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode; + public static final fun filter (Lhep/dataforge/data/DataNode;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/data/DataNode; +} + +public abstract class hep/dataforge/data/DataItem : hep/dataforge/meta/MetaRepr { + public abstract fun getMeta ()Lhep/dataforge/meta/Meta; + public abstract fun getType ()Lkotlin/reflect/KClass; +} + +public final class hep/dataforge/data/DataItem$Leaf : hep/dataforge/data/DataItem { + public fun <init> (Lhep/dataforge/data/Data;)V + public final fun getData ()Lhep/dataforge/data/Data; + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getType ()Lkotlin/reflect/KClass; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/data/DataItem$Node : hep/dataforge/data/DataItem { + public fun <init> (Lhep/dataforge/data/DataNode;)V + public fun getMeta ()Lhep/dataforge/meta/Meta; + public final fun getNode ()Lhep/dataforge/data/DataNode; + public fun getType ()Lkotlin/reflect/KClass; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/data/DataJVMKt { + public static final fun filterIsInstance (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;)Lhep/dataforge/data/Data; + public static final fun filterIsInstance (Lhep/dataforge/data/DataItem;Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataItem; + public static final fun filterIsInstance (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataNode; + public static final fun get (Lhep/dataforge/data/Data;)Ljava/lang/Object; +} + +public final class hep/dataforge/data/DataKt { + public static final fun map (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/Data; + public static synthetic fun map$default (Lhep/dataforge/data/Data;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/Data; + public static final fun reduce (Ljava/util/Map;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/DynamicData; + public static synthetic fun reduce$default (Ljava/util/Map;Lkotlin/reflect/KClass;Lkotlin/coroutines/CoroutineContext;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/DynamicData; +} + +public abstract interface class hep/dataforge/data/DataNode : hep/dataforge/meta/MetaRepr { + public static final field Companion Lhep/dataforge/data/DataNode$Companion; + public static final field TYPE Ljava/lang/String; + public abstract fun getItems ()Ljava/util/Map; + public abstract fun getMeta ()Lhep/dataforge/meta/Meta; + public abstract fun getType ()Lkotlin/reflect/KClass; + public abstract fun startAll (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Job; + public abstract fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/data/DataNode$Companion { + public static final field TYPE Ljava/lang/String; + public final fun builder (Lkotlin/reflect/KClass;)Lhep/dataforge/data/DataTreeBuilder; + public final fun invoke (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/data/DataTree; +} + +public final class hep/dataforge/data/DataNode$DefaultImpls { + public static fun startAll (Lhep/dataforge/data/DataNode;Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Job; + public static fun toMeta (Lhep/dataforge/data/DataNode;)Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/data/DataNodeKt { + public static final fun asSequence (Lhep/dataforge/data/DataNode;)Lkotlin/sequences/Sequence; + public static final fun builder (Lhep/dataforge/data/DataNode;)Lhep/dataforge/data/DataTreeBuilder; + public static final fun dataSequence (Lhep/dataforge/data/DataNode;)Lkotlin/sequences/Sequence; + public static final fun datum (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Lhep/dataforge/data/Data;)V + public static final fun datum (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Lhep/dataforge/data/Data;)V + public static final fun filter (Lhep/dataforge/data/DataNode;Lkotlin/jvm/functions/Function2;)Lhep/dataforge/data/DataNode; + public static final fun first (Lhep/dataforge/data/DataNode;)Lhep/dataforge/data/Data; + public static final fun get (Lhep/dataforge/data/DataNode;Lhep/dataforge/names/Name;)Lhep/dataforge/data/DataItem; + public static final fun get (Lhep/dataforge/data/DataNode;Ljava/lang/String;)Lhep/dataforge/data/DataItem; + public static final fun getData (Lhep/dataforge/data/DataItem;)Lhep/dataforge/data/Data; + public static final fun getNode (Lhep/dataforge/data/DataItem;)Lhep/dataforge/data/DataNode; + public static final fun iterator (Lhep/dataforge/data/DataNode;)Ljava/util/Iterator; + public static final fun join (Lhep/dataforge/data/DataNode;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun node (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Lhep/dataforge/data/DataNode;)V + public static final fun node (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Lhep/dataforge/data/DataNode;)V + public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lhep/dataforge/meta/Meta;)V + public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V + public static final fun static (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;)V + public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)V + public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/names/Name;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public static synthetic fun static$default (Lhep/dataforge/data/DataTreeBuilder;Ljava/lang/String;Ljava/lang/Object;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V +} + +public final class hep/dataforge/data/DataTree : hep/dataforge/data/DataNode { + public fun getItems ()Ljava/util/Map; + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getType ()Lkotlin/reflect/KClass; + public fun startAll (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Job; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/data/DataTreeBuilder { + public fun <init> (Lkotlin/reflect/KClass;)V + public final fun build ()Lhep/dataforge/data/DataTree; + public final fun getType ()Lkotlin/reflect/KClass; + public final fun meta (Lhep/dataforge/meta/Meta;)V + public final fun meta (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MetaBuilder; + public final fun put (Ljava/lang/String;Lhep/dataforge/data/Data;)V + public final fun put (Ljava/lang/String;Lhep/dataforge/data/DataItem;)V + public final fun put (Ljava/lang/String;Lhep/dataforge/data/DataNode;)V + public final fun put (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public final fun set (Lhep/dataforge/names/Name;Lhep/dataforge/data/Data;)V + public final fun set (Lhep/dataforge/names/Name;Lhep/dataforge/data/DataItem;)V + public final fun set (Lhep/dataforge/names/Name;Lhep/dataforge/data/DataNode;)V + public final fun set (Lhep/dataforge/names/Name;Lhep/dataforge/data/DataTreeBuilder;)V + public final fun set (Lhep/dataforge/names/NameToken;Lhep/dataforge/data/Data;)V + public final fun set (Lhep/dataforge/names/NameToken;Lhep/dataforge/data/DataTreeBuilder;)V + public final fun update (Lhep/dataforge/data/DataNode;)V +} + +public final class hep/dataforge/data/Dependencies : kotlin/coroutines/CoroutineContext$Element { + public static final field Companion Lhep/dataforge/data/Dependencies$Companion; + public fun <init> (Ljava/util/Collection;)V + public fun fold (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; + public fun get (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext$Element; + public fun getKey ()Lkotlin/coroutines/CoroutineContext$Key; + public final fun getValues ()Ljava/util/Collection; + public fun minusKey (Lkotlin/coroutines/CoroutineContext$Key;)Lkotlin/coroutines/CoroutineContext; + public fun plus (Lkotlin/coroutines/CoroutineContext;)Lkotlin/coroutines/CoroutineContext; +} + +public final class hep/dataforge/data/Dependencies$Companion : kotlin/coroutines/CoroutineContext$Key { +} + +public final class hep/dataforge/data/DynamicData : hep/dataforge/data/DynamicGoal, hep/dataforge/data/Data { + public fun <init> (Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)V + public synthetic fun <init> (Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getType ()Lkotlin/reflect/KClass; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public class hep/dataforge/data/DynamicGoal : hep/dataforge/data/Goal { + public fun <init> (Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;)V + public synthetic fun <init> (Lkotlin/coroutines/CoroutineContext;Ljava/util/Collection;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getBlock ()Lkotlin/jvm/functions/Function2; + public fun getDependencies ()Ljava/util/Collection; + public final fun getResult ()Lkotlinx/coroutines/Deferred; + public fun reset ()V + public fun startAsync (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Deferred; +} + +public final class hep/dataforge/data/FragmentRule { + public field result Lkotlin/jvm/functions/Function2; + public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaBuilder;)V + public final fun getMeta ()Lhep/dataforge/meta/MetaBuilder; + public final fun getName ()Lhep/dataforge/names/Name; + public final fun getResult ()Lkotlin/jvm/functions/Function2; + public final fun result (Lkotlin/jvm/functions/Function2;)V + public final fun setMeta (Lhep/dataforge/meta/MetaBuilder;)V + public final fun setResult (Lkotlin/jvm/functions/Function2;)V +} + +public abstract interface class hep/dataforge/data/Goal { + public static final field Companion Lhep/dataforge/data/Goal$Companion; + public abstract fun getDependencies ()Ljava/util/Collection; + public abstract fun getResult ()Lkotlinx/coroutines/Deferred; + public abstract fun reset ()V + public abstract fun startAsync (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Deferred; +} + +public final class hep/dataforge/data/Goal$Companion { +} + +public final class hep/dataforge/data/GoalKt { + public static final fun await (Lhep/dataforge/data/Goal;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun isComplete (Lhep/dataforge/data/Goal;)Z + public static final fun map (Lhep/dataforge/data/Goal;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/Goal; + public static synthetic fun map$default (Lhep/dataforge/data/Goal;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/Goal; + public static final fun reduce (Ljava/util/Collection;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/Goal; + public static final fun reduce (Ljava/util/Map;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/data/Goal; + public static synthetic fun reduce$default (Ljava/util/Collection;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/Goal; + public static synthetic fun reduce$default (Ljava/util/Map;Lkotlin/coroutines/CoroutineContext;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/data/Goal; +} + +public abstract interface class hep/dataforge/data/GroupRule { + public static final field Companion Lhep/dataforge/data/GroupRule$Companion; + public abstract fun invoke (Lhep/dataforge/data/DataNode;)Ljava/util/Map; +} + +public final class hep/dataforge/data/GroupRule$Companion { + public final fun byMeta (Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/GroupRule; + public final fun byValue (Ljava/lang/String;Ljava/lang/String;)Lhep/dataforge/data/GroupRule; +} + +public final class hep/dataforge/data/JoinGroup { + public field result Lkotlin/jvm/functions/Function3; + public fun <init> (Ljava/lang/String;Lhep/dataforge/data/DataNode;)V + public final fun getMeta ()Lhep/dataforge/meta/MetaBuilder; + public final fun getName ()Ljava/lang/String; + public final fun getResult ()Lkotlin/jvm/functions/Function3; + public final fun result (Lkotlin/jvm/functions/Function3;)V + public final fun setMeta (Lhep/dataforge/meta/MetaBuilder;)V + public final fun setName (Ljava/lang/String;)V + public final fun setResult (Lkotlin/jvm/functions/Function3;)V +} + +public final class hep/dataforge/data/MapAction : hep/dataforge/data/Action { + public fun <init> (Lkotlin/reflect/KClass;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V + public final fun getInputType ()Lkotlin/reflect/KClass; + public final fun getOutputType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode; + public fun isTerminal ()Z +} + +public final class hep/dataforge/data/MapActionBuilder { + public field result Lkotlin/jvm/functions/Function3; + public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaBuilder;Lhep/dataforge/meta/Meta;)V + public final fun getActionMeta ()Lhep/dataforge/meta/Meta; + public final fun getMeta ()Lhep/dataforge/meta/MetaBuilder; + public final fun getName ()Lhep/dataforge/names/Name; + public final fun getResult ()Lkotlin/jvm/functions/Function3; + public final fun result (Lkotlin/jvm/functions/Function3;)V + public final fun setMeta (Lhep/dataforge/meta/MetaBuilder;)V + public final fun setName (Lhep/dataforge/names/Name;)V + public final fun setResult (Lkotlin/jvm/functions/Function3;)V +} + +public final class hep/dataforge/data/NamedData : hep/dataforge/data/Data { + public fun <init> (Ljava/lang/String;Lhep/dataforge/data/Data;)V + public fun getDependencies ()Ljava/util/Collection; + public fun getMeta ()Lhep/dataforge/meta/Meta; + public final fun getName ()Ljava/lang/String; + public fun getResult ()Lkotlinx/coroutines/Deferred; + public fun getType ()Lkotlin/reflect/KClass; + public fun reset ()V + public fun startAsync (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Deferred; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/data/ReduceAction : hep/dataforge/data/Action { + public fun <init> (Lkotlin/reflect/KClass;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V + public final fun getInputType ()Lkotlin/reflect/KClass; + public final fun getOutputType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode; + public fun isTerminal ()Z +} + +public final class hep/dataforge/data/ReduceActionKt { + public static final fun get (Ljava/util/Map;Ljava/lang/String;)Ljava/lang/Object; +} + +public final class hep/dataforge/data/ReduceGroupBuilder { + public fun <init> (Lhep/dataforge/meta/Meta;)V + public final fun byValue (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public static synthetic fun byValue$default (Lhep/dataforge/data/ReduceGroupBuilder;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public final fun getActionMeta ()Lhep/dataforge/meta/Meta; + public final fun group (Ljava/lang/String;Lhep/dataforge/data/DataFilter;Lkotlin/jvm/functions/Function1;)V + public final fun group (Ljava/lang/String;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)V + public final fun result (Ljava/lang/String;Lkotlin/jvm/functions/Function3;)V +} + +public final class hep/dataforge/data/SplitAction : hep/dataforge/data/Action { + public fun <init> (Lkotlin/reflect/KClass;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V + public final fun getInputType ()Lkotlin/reflect/KClass; + public final fun getOutputType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/data/DataNode;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode; + public fun isTerminal ()Z +} + +public final class hep/dataforge/data/SplitBuilder { + public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V + public final fun fragment (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public final fun getMeta ()Lhep/dataforge/meta/Meta; + public final fun getName ()Lhep/dataforge/names/Name; +} + +public final class hep/dataforge/data/StaticData : hep/dataforge/data/StaticGoal, hep/dataforge/data/Data { + public fun <init> (Ljava/lang/Object;Lhep/dataforge/meta/Meta;)V + public synthetic fun <init> (Ljava/lang/Object;Lhep/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getType ()Lkotlin/reflect/KClass; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public class hep/dataforge/data/StaticGoal : hep/dataforge/data/Goal { + public fun <init> (Ljava/lang/Object;)V + public fun getDependencies ()Ljava/util/Collection; + public fun getResult ()Lkotlinx/coroutines/Deferred; + public final fun getValue ()Ljava/lang/Object; + public fun reset ()V + public fun startAsync (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Deferred; +} + +public final class hep/dataforge/data/TypeFilteredDataNode : hep/dataforge/data/DataNode { + public fun <init> (Lhep/dataforge/data/DataNode;Lkotlin/reflect/KClass;)V + public fun getItems ()Ljava/util/Map; + public fun getMeta ()Lhep/dataforge/meta/Meta; + public final fun getOrigin ()Lhep/dataforge/data/DataNode; + public fun getType ()Lkotlin/reflect/KClass; + public fun startAll (Lkotlinx/coroutines/CoroutineScope;)Lkotlinx/coroutines/Job; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + diff --git a/dataforge-data/build.gradle.kts b/dataforge-data/build.gradle.kts index 793f551b..436d9428 100644 --- a/dataforge-data/build.gradle.kts +++ b/dataforge-data/build.gradle.kts @@ -1,29 +1,23 @@ plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") + id("ru.mipt.npm.native") } -val coroutinesVersion: String = Scientifik.coroutinesVersion +kscience{ + useCoroutines() +} kotlin { sourceSets { - val commonMain by getting{ + commonMain{ dependencies { api(project(":dataforge-meta")) - api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:$coroutinesVersion") } } - - val jvmMain by getting{ - dependencies { - api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion") + jvmMain{ + dependencies{ api(kotlin("reflect")) } } - - val jsMain by getting{ - dependencies { - api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:$coroutinesVersion") - } - } } } \ No newline at end of file diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Action.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Action.kt index cf030c75..d747587e 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Action.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Action.kt @@ -5,23 +5,23 @@ import hep.dataforge.meta.Meta /** * A simple data transformation on a data node */ -interface Action<in T : Any, out R : Any> { +public interface Action<in T : Any, out R : Any> { /** * Transform the data in the node, producing a new node. By default it is assumed that all calculations are lazy * so not actual computation is started at this moment */ - operator fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> + public operator fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> /** * Terminal action is the one that could not be invoked lazily and requires some kind of blocking computation to invoke */ - val isTerminal: Boolean get() = false + public val isTerminal: Boolean get() = false } /** * Action composition. The result is terminal if one of its parts is terminal */ -infix fun <T : Any, I : Any, R : Any> Action<T, I>.then(action: Action<I, R>): Action<T, R> { +public infix fun <T : Any, I : Any, R : Any> Action<T, I>.then(action: Action<I, R>): Action<T, R> { // TODO introduce composite action and add optimize by adding action to the list return object : Action<T, R> { override fun invoke(node: DataNode<T>, meta: Meta): DataNode<R> { diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/CoroutineMonitor.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/CoroutineMonitor.kt index 8cbd6192..d1c0d55e 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/CoroutineMonitor.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/CoroutineMonitor.kt @@ -1,48 +1,58 @@ package hep.dataforge.data +import hep.dataforge.meta.DFExperimental import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlin.coroutines.CoroutineContext + + /** * A monitor of goal state that could be accessed only form inside the goal */ -class CoroutineMonitor : CoroutineContext.Element { +@DFExperimental +public class CoroutineMonitor : CoroutineContext.Element { override val key: CoroutineContext.Key<*> get() = CoroutineMonitor - var totalWork: Double = 1.0 - var workDone: Double = 0.0 - var status: String = "" + public var totalWork: Double = 1.0 + public var workDone: Double = 0.0 + public var status: String = "" /** * Mark the goal as started */ - fun start() { + public fun start() { } /** * Mark the goal as completed */ - fun finish() { + public fun finish() { workDone = totalWork } - companion object : CoroutineContext.Key<CoroutineMonitor> + public companion object : CoroutineContext.Key<CoroutineMonitor> } -class Dependencies(val values: Collection<Job>) : CoroutineContext.Element { +public class Dependencies(public val values: Collection<Job>) : CoroutineContext.Element { override val key: CoroutineContext.Key<*> get() = Dependencies - companion object : CoroutineContext.Key<Dependencies> + public companion object : CoroutineContext.Key<Dependencies> } -val CoroutineContext.monitor: CoroutineMonitor? get() = this[CoroutineMonitor] -val CoroutineScope.monitor: CoroutineMonitor? get() = coroutineContext.monitor +@DFExperimental +public val CoroutineContext.monitor: CoroutineMonitor? get() = this[CoroutineMonitor] +@DFExperimental +public val CoroutineScope.monitor: CoroutineMonitor? get() = coroutineContext.monitor -val Job.dependencies: Collection<Job> get() = this[Dependencies]?.values ?: emptyList() +public val Job.dependencies: Collection<Job> get() = this[Dependencies]?.values ?: emptyList() -val Job.totalWork: Double get() = dependencies.sumByDouble { totalWork } + (monitor?.totalWork ?: 0.0) -val Job.workDone: Double get() = dependencies.sumByDouble { workDone } + (monitor?.workDone ?: 0.0) -val Job.status: String get() = monitor?.status ?: "" -val Job.progress: Double get() = workDone / totalWork \ No newline at end of file +@DFExperimental +public val Job.totalWork: Double get() = dependencies.sumByDouble { totalWork } + (monitor?.totalWork ?: 0.0) +@DFExperimental +public val Job.workDone: Double get() = dependencies.sumByDouble { workDone } + (monitor?.workDone ?: 0.0) +@DFExperimental +public val Job.status: String get() = monitor?.status ?: "" +@DFExperimental +public val Job.progress: Double get() = workDone / totalWork \ No newline at end of file diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Data.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Data.kt index 233ea164..c573aad8 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Data.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Data.kt @@ -11,15 +11,16 @@ import kotlin.reflect.KClass /** * A data element characterized by its meta */ -interface Data<out T : Any> : Goal<T>, MetaRepr{ +public interface Data<out T : Any> : Goal<T>, MetaRepr{ /** * Type marker for the data. The type is known before the calculation takes place so it could be checked. */ - val type: KClass<out T> + public val type: KClass<out T> + /** * Meta for the data */ - val meta: Meta + public val meta: Meta override fun toMeta(): Meta = Meta { "type" put (type.simpleName?:"undefined") @@ -28,10 +29,10 @@ interface Data<out T : Any> : Goal<T>, MetaRepr{ } } - companion object { - const val TYPE = "data" + public companion object { + public const val TYPE: String = "data" - operator fun <T : Any> invoke( + public operator fun <T : Any> invoke( type: KClass<out T>, meta: Meta = Meta.EMPTY, context: CoroutineContext = EmptyCoroutineContext, @@ -39,14 +40,14 @@ interface Data<out T : Any> : Goal<T>, MetaRepr{ block: suspend CoroutineScope.() -> T ): Data<T> = DynamicData(type, meta, context, dependencies, block) - inline operator fun <reified T : Any> invoke( + public inline operator fun <reified T : Any> invoke( meta: Meta = Meta.EMPTY, context: CoroutineContext = EmptyCoroutineContext, dependencies: Collection<Data<*>> = emptyList(), noinline block: suspend CoroutineScope.() -> T ): Data<T> = invoke(T::class, meta, context, dependencies, block) - operator fun <T : Any> invoke( + public operator fun <T : Any> invoke( name: String, type: KClass<out T>, meta: Meta = Meta.EMPTY, @@ -55,7 +56,7 @@ interface Data<out T : Any> : Goal<T>, MetaRepr{ block: suspend CoroutineScope.() -> T ): Data<T> = NamedData(name, invoke(type, meta, context, dependencies, block)) - inline operator fun <reified T : Any> invoke( + public inline operator fun <reified T : Any> invoke( name: String, meta: Meta = Meta.EMPTY, context: CoroutineContext = EmptyCoroutineContext, @@ -64,13 +65,13 @@ interface Data<out T : Any> : Goal<T>, MetaRepr{ ): Data<T> = invoke(name, T::class, meta, context, dependencies, block) - fun <T : Any> static(value: T, meta: Meta = Meta.EMPTY): Data<T> = + public fun <T : Any> static(value: T, meta: Meta = Meta.EMPTY): Data<T> = StaticData(value, meta) } } -class DynamicData<T : Any>( +public class DynamicData<T : Any>( override val type: KClass<out T>, override val meta: Meta = Meta.EMPTY, context: CoroutineContext = EmptyCoroutineContext, @@ -78,16 +79,16 @@ class DynamicData<T : Any>( block: suspend CoroutineScope.() -> T ) : Data<T>, DynamicGoal<T>(context, dependencies, block) -class StaticData<T : Any>( +public class StaticData<T : Any>( value: T, override val meta: Meta = Meta.EMPTY ) : Data<T>, StaticGoal<T>(value) { override val type: KClass<out T> get() = value::class } -class NamedData<out T : Any>(val name: String, data: Data<T>) : Data<T> by data +public class NamedData<out T : Any>(public val name: String, data: Data<T>) : Data<T> by data -fun <T : Any, R : Any> Data<T>.map( +public fun <T : Any, R : Any> Data<T>.map( outputType: KClass<out R>, coroutineContext: CoroutineContext = EmptyCoroutineContext, meta: Meta = this.meta, @@ -100,7 +101,7 @@ fun <T : Any, R : Any> Data<T>.map( /** * Create a data pipe */ -inline fun <T : Any, reified R : Any> Data<T>.map( +public inline fun <T : Any, reified R : Any> Data<T>.map( coroutineContext: CoroutineContext = EmptyCoroutineContext, meta: Meta = this.meta, noinline block: suspend CoroutineScope.(T) -> R @@ -111,7 +112,7 @@ inline fun <T : Any, reified R : Any> Data<T>.map( /** * Create a joined data. */ -inline fun <T : Any, reified R : Any> Collection<Data<T>>.reduce( +public inline fun <T : Any, reified R : Any> Collection<Data<T>>.reduce( coroutineContext: CoroutineContext = EmptyCoroutineContext, meta: Meta, noinline block: suspend CoroutineScope.(Collection<T>) -> R @@ -124,7 +125,7 @@ inline fun <T : Any, reified R : Any> Collection<Data<T>>.reduce( block(map { run { it.await() } }) } -fun <K, T : Any, R : Any> Map<K, Data<T>>.reduce( +public fun <K, T : Any, R : Any> Map<K, Data<T>>.reduce( outputType: KClass<out R>, coroutineContext: CoroutineContext = EmptyCoroutineContext, meta: Meta, @@ -145,7 +146,7 @@ fun <K, T : Any, R : Any> Map<K, Data<T>>.reduce( * @param T type of the input goal * @param R type of the result goal */ -inline fun <K, T : Any, reified R : Any> Map<K, Data<T>>.reduce( +public inline fun <K, T : Any, reified R : Any> Map<K, Data<T>>.reduce( coroutineContext: CoroutineContext = EmptyCoroutineContext, meta: Meta, noinline block: suspend CoroutineScope.(Map<K, T>) -> R diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt index b24f87a2..df19acd0 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataFilter.kt @@ -4,31 +4,29 @@ import hep.dataforge.meta.* import hep.dataforge.names.toName -class DataFilter : Scheme() { +public class DataFilter : Scheme() { /** * A source node for the filter */ - var from by string() + public var from: String? by string() /** * A target placement for the filtered node */ - var to by string() + public var to: String? by string() /** * A regular expression pattern for the filter */ - var pattern by string(".*") + public var pattern: String by string(".*") // val prefix by string() // val suffix by string() - fun isEmpty(): Boolean = config.isEmpty() - - companion object : SchemeSpec<DataFilter>(::DataFilter) + public companion object : SchemeSpec<DataFilter>(::DataFilter) } /** * Apply meta-based filter to given data node */ -fun <T : Any> DataNode<T>.filter(filter: DataFilter): DataNode<T> { +public fun <T : Any> DataNode<T>.filter(filter: DataFilter): DataNode<T> { val sourceNode = filter.from?.let { get(it.toName()).node } ?: this@filter val regex = filter.pattern.toRegex() val targetNode = DataTreeBuilder(type).apply { @@ -46,10 +44,10 @@ fun <T : Any> DataNode<T>.filter(filter: DataFilter): DataNode<T> { /** * Filter data using [DataFilter] specification */ -fun <T : Any> DataNode<T>.filter(filter: Meta): DataNode<T> = filter(DataFilter.wrap(filter)) +public fun <T : Any> DataNode<T>.filter(filter: Meta): DataNode<T> = filter(DataFilter.read(filter)) /** * Filter data using [DataFilter] builder */ -fun <T : Any> DataNode<T>.filter(filterBuilder: DataFilter.() -> Unit): DataNode<T> = +public fun <T : Any> DataNode<T>.filter(filterBuilder: DataFilter.() -> Unit): DataNode<T> = filter(DataFilter(filterBuilder)) \ No newline at end of file diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataNode.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataNode.kt index 246d9796..23fea9ef 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataNode.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/DataNode.kt @@ -11,12 +11,12 @@ import kotlin.collections.component2 import kotlin.collections.set import kotlin.reflect.KClass -sealed class DataItem<out T : Any> : MetaRepr { - abstract val type: KClass<out T> +public sealed class DataItem<out T : Any> : MetaRepr { + public abstract val type: KClass<out T> - abstract val meta: Meta + public abstract val meta: Meta - class Node<out T : Any>(val node: DataNode<T>) : DataItem<T>() { + public class Node<out T : Any>(public val node: DataNode<T>) : DataItem<T>() { override val type: KClass<out T> get() = node.type override fun toMeta(): Meta = node.toMeta() @@ -24,7 +24,7 @@ sealed class DataItem<out T : Any> : MetaRepr { override val meta: Meta get() = node.meta } - class Leaf<out T : Any>(val data: Data<T>) : DataItem<T>() { + public class Leaf<out T : Any>(public val data: Data<T>) : DataItem<T>() { override val type: KClass<out T> get() = data.type override fun toMeta(): Meta = data.toMeta() @@ -36,16 +36,16 @@ sealed class DataItem<out T : Any> : MetaRepr { /** * A tree-like data structure grouped into the node. All data inside the node must inherit its type */ -interface DataNode<out T : Any> : MetaRepr { +public interface DataNode<out T : Any> : MetaRepr { /** * The minimal common ancestor to all data in the node */ - val type: KClass<out T> + public val type: KClass<out T> - val items: Map<NameToken, DataItem<T>> + public val items: Map<NameToken, DataItem<T>> - val meta: Meta + public val meta: Meta override fun toMeta(): Meta = Meta { "type" put (type.simpleName ?: "undefined") @@ -60,7 +60,7 @@ interface DataNode<out T : Any> : MetaRepr { * Start computation for all goals in data node and return a job for the whole node */ @Suppress("DeferredResultUnused") - fun CoroutineScope.startAll(): Job = launch { + public fun CoroutineScope.startAll(): Job = launch { items.values.forEach { when (it) { is DataItem.Node<*> -> it.node.run { startAll() } @@ -69,36 +69,36 @@ interface DataNode<out T : Any> : MetaRepr { } } - companion object { - const val TYPE = "dataNode" + public companion object { + public const val TYPE: String = "dataNode" - operator fun <T : Any> invoke(type: KClass<out T>, block: DataTreeBuilder<T>.() -> Unit) = + public operator fun <T : Any> invoke(type: KClass<out T>, block: DataTreeBuilder<T>.() -> Unit): DataTree<T> = DataTreeBuilder(type).apply(block).build() - inline operator fun <reified T : Any> invoke(noinline block: DataTreeBuilder<T>.() -> Unit) = + public inline operator fun <reified T : Any> invoke(noinline block: DataTreeBuilder<T>.() -> Unit): DataTree<T> = DataTreeBuilder(T::class).apply(block).build() - fun <T : Any> builder(type: KClass<out T>) = DataTreeBuilder(type) + public fun <T : Any> builder(type: KClass<out T>): DataTreeBuilder<T> = DataTreeBuilder(type) } } -suspend fun <T: Any> DataNode<T>.join(): Unit = coroutineScope { startAll().join() } +public suspend fun <T: Any> DataNode<T>.join(): Unit = coroutineScope { startAll().join() } -val <T : Any> DataItem<T>?.node: DataNode<T>? get() = (this as? DataItem.Node<T>)?.node -val <T : Any> DataItem<T>?.data: Data<T>? get() = (this as? DataItem.Leaf<T>)?.data +public val <T : Any> DataItem<T>?.node: DataNode<T>? get() = (this as? DataItem.Node<T>)?.node +public val <T : Any> DataItem<T>?.data: Data<T>? get() = (this as? DataItem.Leaf<T>)?.data -operator fun <T : Any> DataNode<T>.get(name: Name): DataItem<T>? = when (name.length) { +public operator fun <T : Any> DataNode<T>.get(name: Name): DataItem<T>? = when (name.length) { 0 -> error("Empty name") - 1 -> items[name.first()] - else -> get(name.first()!!.asName()).node?.get(name.cutFirst()) + 1 -> items[name.firstOrNull()] + else -> get(name.firstOrNull()!!.asName()).node?.get(name.cutFirst()) } -operator fun <T : Any> DataNode<T>.get(name: String): DataItem<T>? = get(name.toName()) +public operator fun <T : Any> DataNode<T>.get(name: String): DataItem<T>? = get(name.toName()) /** * Sequence of all children including nodes */ -fun <T : Any> DataNode<T>.asSequence(): Sequence<Pair<Name, DataItem<T>>> = sequence { +public fun <T : Any> DataNode<T>.asSequence(): Sequence<Pair<Name, DataItem<T>>> = sequence { items.forEach { (head, item) -> yield(head.asName() to item) if (item is DataItem.Node) { @@ -112,7 +112,7 @@ fun <T : Any> DataNode<T>.asSequence(): Sequence<Pair<Name, DataItem<T>>> = sequ /** * Sequence of data entries */ -fun <T : Any> DataNode<T>.dataSequence(): Sequence<Pair<Name, Data<T>>> = sequence { +public fun <T : Any> DataNode<T>.dataSequence(): Sequence<Pair<Name, Data<T>>> = sequence { items.forEach { (head, item) -> when (item) { is DataItem.Leaf -> yield(head.asName() to item.data) @@ -125,9 +125,9 @@ fun <T : Any> DataNode<T>.dataSequence(): Sequence<Pair<Name, Data<T>>> = sequen } } -operator fun <T : Any> DataNode<T>.iterator(): Iterator<Pair<Name, DataItem<T>>> = asSequence().iterator() +public operator fun <T : Any> DataNode<T>.iterator(): Iterator<Pair<Name, DataItem<T>>> = asSequence().iterator() -class DataTree<out T : Any> internal constructor( +public class DataTree<out T : Any> internal constructor( override val type: KClass<out T>, override val items: Map<NameToken, DataItem<T>>, override val meta: Meta @@ -142,17 +142,17 @@ private sealed class DataTreeBuilderItem<out T : Any> { * A builder for a DataTree. */ @DFBuilder -class DataTreeBuilder<T : Any>(val type: KClass<out T>) { +public class DataTreeBuilder<T : Any>(public val type: KClass<out T>) { private val map = HashMap<NameToken, DataTreeBuilderItem<T>>() private var meta = MetaBuilder() - operator fun set(token: NameToken, node: DataTreeBuilder<out T>) { + public operator fun set(token: NameToken, node: DataTreeBuilder<out T>) { if (map.containsKey(token)) error("Tree entry with name $token is not empty") map[token] = DataTreeBuilderItem.Node(node) } - operator fun set(token: NameToken, data: Data<T>) { + public operator fun set(token: NameToken, data: Data<T>) { if (map.containsKey(token)) error("Tree entry with name $token is not empty") map[token] = DataTreeBuilderItem.Leaf(data) } @@ -168,30 +168,30 @@ class DataTreeBuilder<T : Any>(val type: KClass<out T>) { private fun buildNode(name: Name): DataTreeBuilder<T> { return when (name.length) { 0 -> this - 1 -> buildNode(name.first()!!) - else -> buildNode(name.first()!!).buildNode(name.cutFirst()) + 1 -> buildNode(name.firstOrNull()!!) + else -> buildNode(name.firstOrNull()!!).buildNode(name.cutFirst()) } } - operator fun set(name: Name, data: Data<T>) { + public operator fun set(name: Name, data: Data<T>) { when (name.length) { 0 -> error("Can't add data with empty name") - 1 -> set(name.first()!!, data) - 2 -> buildNode(name.cutLast())[name.last()!!] = data + 1 -> set(name.firstOrNull()!!, data) + 2 -> buildNode(name.cutLast())[name.lastOrNull()!!] = data } } - operator fun set(name: Name, node: DataTreeBuilder<out T>) { + public operator fun set(name: Name, node: DataTreeBuilder<out T>) { when (name.length) { 0 -> error("Can't add data with empty name") - 1 -> set(name.first()!!, node) - 2 -> buildNode(name.cutLast())[name.last()!!] = node + 1 -> set(name.firstOrNull()!!, node) + 2 -> buildNode(name.cutLast())[name.lastOrNull()!!] = node } } - operator fun set(name: Name, node: DataNode<T>) = set(name, node.builder()) + public operator fun set(name: Name, node: DataNode<T>): Unit = set(name, node.builder()) - operator fun set(name: Name, item: DataItem<T>) = when (item) { + public operator fun set(name: Name, item: DataItem<T>): Unit = when (item) { is DataItem.Node<T> -> set(name, item.node.builder()) is DataItem.Leaf<T> -> set(name, item.data) } @@ -199,25 +199,25 @@ class DataTreeBuilder<T : Any>(val type: KClass<out T>) { /** * Append data to node */ - infix fun String.put(data: Data<T>) = set(toName(), data) + public infix fun String.put(data: Data<T>): Unit = set(toName(), data) /** * Append node */ - infix fun String.put(node: DataNode<T>) = set(toName(), node) + public infix fun String.put(node: DataNode<T>): Unit = set(toName(), node) - infix fun String.put(item: DataItem<T>) = set(toName(), item) + public infix fun String.put(item: DataItem<T>): Unit = set(toName(), item) /** * Build and append node */ - infix fun String.put(block: DataTreeBuilder<T>.() -> Unit) = set(toName(), DataTreeBuilder(type).apply(block)) + public infix fun String.put(block: DataTreeBuilder<T>.() -> Unit): Unit = set(toName(), DataTreeBuilder(type).apply(block)) /** * Update data with given node data and meta with node meta. */ - fun update(node: DataNode<T>) { + public fun update(node: DataNode<T>) { node.dataSequence().forEach { //TODO check if the place is occupied this[it.first] = it.second @@ -225,13 +225,13 @@ class DataTreeBuilder<T : Any>(val type: KClass<out T>) { meta.update(node.meta) } - fun meta(block: MetaBuilder.() -> Unit) = meta.apply(block) + public fun meta(block: MetaBuilder.() -> Unit): MetaBuilder = meta.apply(block) - fun meta(meta: Meta) { + public fun meta(meta: Meta) { this.meta = meta.builder() } - fun build(): DataTree<T> { + public fun build(): DataTree<T> { val resMap = map.mapValues { (_, value) -> when (value) { is DataTreeBuilderItem.Leaf -> DataItem.Leaf(value.value) @@ -242,50 +242,50 @@ class DataTreeBuilder<T : Any>(val type: KClass<out T>) { } } -fun <T : Any> DataTreeBuilder<T>.datum(name: Name, data: Data<T>) { +public fun <T : Any> DataTreeBuilder<T>.datum(name: Name, data: Data<T>) { this[name] = data } -fun <T : Any> DataTreeBuilder<T>.datum(name: String, data: Data<T>) { +public fun <T : Any> DataTreeBuilder<T>.datum(name: String, data: Data<T>) { this[name.toName()] = data } -fun <T : Any> DataTreeBuilder<T>.static(name: Name, data: T, meta: Meta = Meta.EMPTY) { +public fun <T : Any> DataTreeBuilder<T>.static(name: Name, data: T, meta: Meta = Meta.EMPTY) { this[name] = Data.static(data, meta) } -fun <T : Any> DataTreeBuilder<T>.static(name: Name, data: T, block: MetaBuilder.() -> Unit = {}) { +public fun <T : Any> DataTreeBuilder<T>.static(name: Name, data: T, block: MetaBuilder.() -> Unit = {}) { this[name] = Data.static(data, Meta(block)) } -fun <T : Any> DataTreeBuilder<T>.static(name: String, data: T, block: MetaBuilder.() -> Unit = {}) { +public fun <T : Any> DataTreeBuilder<T>.static(name: String, data: T, block: MetaBuilder.() -> Unit = {}) { this[name.toName()] = Data.static(data, Meta(block)) } -fun <T : Any> DataTreeBuilder<T>.node(name: Name, node: DataNode<T>) { +public fun <T : Any> DataTreeBuilder<T>.node(name: Name, node: DataNode<T>) { this[name] = node } -fun <T : Any> DataTreeBuilder<T>.node(name: String, node: DataNode<T>) { +public fun <T : Any> DataTreeBuilder<T>.node(name: String, node: DataNode<T>) { this[name.toName()] = node } -inline fun <reified T : Any> DataTreeBuilder<T>.node(name: Name, noinline block: DataTreeBuilder<T>.() -> Unit) { +public inline fun <reified T : Any> DataTreeBuilder<T>.node(name: Name, noinline block: DataTreeBuilder<T>.() -> Unit) { this[name] = DataNode(T::class, block) } -inline fun <reified T : Any> DataTreeBuilder<T>.node(name: String, noinline block: DataTreeBuilder<T>.() -> Unit) { +public inline fun <reified T : Any> DataTreeBuilder<T>.node(name: String, noinline block: DataTreeBuilder<T>.() -> Unit) { this[name.toName()] = DataNode(T::class, block) } /** * Generate a mutable builder from this node. Node content is not changed */ -fun <T : Any> DataNode<T>.builder(): DataTreeBuilder<T> = DataTreeBuilder(type).apply { +public fun <T : Any> DataNode<T>.builder(): DataTreeBuilder<T> = DataTreeBuilder(type).apply { dataSequence().forEach { (name, data) -> this[name] = data } } -fun <T : Any> DataNode<T>.filter(predicate: (Name, Data<T>) -> Boolean): DataNode<T> = DataNode.invoke(type) { +public fun <T : Any> DataNode<T>.filter(predicate: (Name, Data<T>) -> Boolean): DataNode<T> = DataNode.invoke(type) { dataSequence().forEach { (name, data) -> if (predicate(name, data)) { this[name] = data @@ -293,4 +293,4 @@ fun <T : Any> DataNode<T>.filter(predicate: (Name, Data<T>) -> Boolean): DataNod } } -fun <T : Any> DataNode<T>.first(): Data<T>? = dataSequence().first().second \ No newline at end of file +public fun <T : Any> DataNode<T>.first(): Data<T>? = dataSequence().first().second \ No newline at end of file diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Goal.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Goal.kt index 8c0eeec7..e5050d22 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Goal.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/Goal.kt @@ -1,37 +1,36 @@ package hep.dataforge.data +import hep.dataforge.meta.DFExperimental import kotlinx.coroutines.* import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext -interface Goal<out T> { - val dependencies: Collection<Goal<*>> +public interface Goal<out T> { + public val dependencies: Collection<Goal<*>> /** * Returns current running coroutine if the goal is started */ - val result: Deferred<T>? + public val result: Deferred<T>? /** * Get ongoing computation or start a new one. * Does not guarantee thread safety. In case of multi-thread access, could create orphan computations. */ - fun CoroutineScope.startAsync(): Deferred<T> + public fun CoroutineScope.startAsync(): Deferred<T> /** * Reset the computation */ - fun reset() + public fun reset() - companion object { - - } + public companion object } -suspend fun <T> Goal<T>.await(): T = coroutineScope { startAsync().await() } +public suspend fun <T> Goal<T>.await(): T = coroutineScope { startAsync().await() } -val Goal<*>.isComplete get() = result?.isCompleted ?: false +public val Goal<*>.isComplete: Boolean get() = result?.isCompleted ?: false -open class StaticGoal<T>(val value: T) : Goal<T> { +public open class StaticGoal<T>(public val value: T) : Goal<T> { override val dependencies: Collection<Goal<*>> get() = emptyList() override val result: Deferred<T> = CompletableDeferred(value) @@ -42,10 +41,10 @@ open class StaticGoal<T>(val value: T) : Goal<T> { } } -open class DynamicGoal<T>( - val coroutineContext: CoroutineContext = EmptyCoroutineContext, +public open class DynamicGoal<T>( + private val coroutineContext: CoroutineContext = EmptyCoroutineContext, override val dependencies: Collection<Goal<*>> = emptyList(), - val block: suspend CoroutineScope.() -> T + public val block: suspend CoroutineScope.() -> T ) : Goal<T> { final override var result: Deferred<T>? = null @@ -55,6 +54,7 @@ open class DynamicGoal<T>( * Get ongoing computation or start a new one. * Does not guarantee thread safety. In case of multi-thread access, could create orphan computations. */ + @DFExperimental override fun CoroutineScope.startAsync(): Deferred<T> { val startedDependencies = this@DynamicGoal.dependencies.map { goal -> goal.run { startAsync() } @@ -82,7 +82,7 @@ open class DynamicGoal<T>( /** * Create a one-to-one goal based on existing goal */ -fun <T, R> Goal<T>.map( +public fun <T, R> Goal<T>.map( coroutineContext: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.(T) -> R ): Goal<R> = DynamicGoal(coroutineContext, listOf(this)) { @@ -92,7 +92,7 @@ fun <T, R> Goal<T>.map( /** * Create a joining goal. */ -fun <T, R> Collection<Goal<T>>.reduce( +public fun <T, R> Collection<Goal<T>>.reduce( coroutineContext: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.(Collection<T>) -> R ): Goal<R> = DynamicGoal(coroutineContext, this) { @@ -105,7 +105,7 @@ fun <T, R> Collection<Goal<T>>.reduce( * @param T type of the input goal * @param R type of the result goal */ -fun <K, T, R> Map<K, Goal<T>>.reduce( +public fun <K, T, R> Map<K, Goal<T>>.reduce( coroutineContext: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.(Map<K, T>) -> R ): Goal<R> = DynamicGoal(coroutineContext, this.values) { diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/GroupRule.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/GroupRule.kt index 5cfc55e8..0a5de778 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/GroupRule.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/GroupRule.kt @@ -19,10 +19,10 @@ import hep.dataforge.meta.Meta import hep.dataforge.meta.get import hep.dataforge.meta.string -interface GroupRule { - operator fun <T : Any> invoke(node: DataNode<T>): Map<String, DataNode<T>> +public interface GroupRule { + public operator fun <T : Any> invoke(node: DataNode<T>): Map<String, DataNode<T>> - companion object{ + public companion object{ /** * Create grouping rule that creates groups for different values of value * field with name [key] @@ -31,7 +31,7 @@ interface GroupRule { * @param defaultTagValue * @return */ - fun byValue(key: String, defaultTagValue: String): GroupRule = object : + public fun byValue(key: String, defaultTagValue: String): GroupRule = object : GroupRule { override fun <T : Any> invoke(node: DataNode<T>): Map<String, DataNode<T>> { val map = HashMap<String, DataTreeBuilder<T>>() @@ -52,7 +52,7 @@ interface GroupRule { // def = "default", // info = "Default value which should be used for content in which the grouping value is not presented" // ) - fun byMeta(config: Meta): GroupRule { + public fun byMeta(config: Meta): GroupRule { //TODO expand grouping options return config["byValue"]?.string?.let { byValue( diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/MapAction.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/MapAction.kt index 61598349..e5504530 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/MapAction.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/MapAction.kt @@ -7,32 +7,31 @@ import kotlin.reflect.KClass /** * Action environment includes data name, data meta and action configuration meta */ -data class ActionEnv( +public data class ActionEnv( val name: Name, val meta: Meta, val actionMeta: Meta ) - /** * Action environment */ @DFBuilder -class MapActionBuilder<T, R>(var name: Name, var meta: MetaBuilder, val actionMeta: Meta) { - lateinit var result: suspend ActionEnv.(T) -> R +public class MapActionBuilder<T, R>(public var name: Name, public var meta: MetaBuilder, public val actionMeta: Meta) { + public lateinit var result: suspend ActionEnv.(T) -> R /** * Calculate the result of goal */ - fun result(f: suspend ActionEnv.(T) -> R) { + public fun result(f: suspend ActionEnv.(T) -> R) { result = f; } } -class MapAction<T : Any, out R : Any>( - val inputType: KClass<T>, - val outputType: KClass<out R>, +public class MapAction<T : Any, out R : Any>( + public val inputType: KClass<T>, + public val outputType: KClass<out R>, private val block: MapActionBuilder<T, R>.() -> Unit ) : Action<T, R> { @@ -67,7 +66,7 @@ class MapAction<T : Any, out R : Any>( } } -inline fun <reified T : Any, reified R : Any> DataNode<T>.map( +public inline fun <reified T : Any, reified R : Any> DataNode<T>.map( meta: Meta, noinline action: MapActionBuilder<in T, out R>.() -> Unit ): DataNode<R> = MapAction(T::class, R::class, action).invoke(this, meta) diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/ReduceAction.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/ReduceAction.kt index 0efb5506..a0227af9 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/ReduceAction.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/ReduceAction.kt @@ -7,25 +7,25 @@ import hep.dataforge.names.toName import kotlin.reflect.KClass -class JoinGroup<T : Any, R : Any>(var name: String, internal val node: DataNode<T>) { +public class JoinGroup<T : Any, R : Any>(public var name: String, internal val node: DataNode<T>) { - var meta: MetaBuilder = MetaBuilder() + public var meta: MetaBuilder = MetaBuilder() - lateinit var result: suspend ActionEnv.(Map<Name, T>) -> R + public lateinit var result: suspend ActionEnv.(Map<Name, T>) -> R - fun result(f: suspend ActionEnv.(Map<Name, T>) -> R) { + public fun result(f: suspend ActionEnv.(Map<Name, T>) -> R) { this.result = f; } } -class ReduceGroupBuilder<T : Any, R : Any>(val actionMeta: Meta) { +public class ReduceGroupBuilder<T : Any, R : Any>(public val actionMeta: Meta) { private val groupRules: MutableList<(DataNode<T>) -> List<JoinGroup<T, R>>> = ArrayList(); /** * introduce grouping by value name */ - fun byValue(tag: String, defaultTag: String = "@default", action: JoinGroup<T, R>.() -> Unit) { + public fun byValue(tag: String, defaultTag: String = "@default", action: JoinGroup<T, R>.() -> Unit) { groupRules += { node -> GroupRule.byValue(tag, defaultTag).invoke(node).map { JoinGroup<T, R>(it.key, it.value).apply(action) @@ -36,7 +36,7 @@ class ReduceGroupBuilder<T : Any, R : Any>(val actionMeta: Meta) { /** * Add a single fixed group to grouping rules */ - fun group(groupName: String, filter: DataFilter, action: JoinGroup<T, R>.() -> Unit) { + public fun group(groupName: String, filter: DataFilter, action: JoinGroup<T, R>.() -> Unit) { groupRules += { node -> listOf( JoinGroup<T, R>(groupName, node.filter(filter)).apply(action) @@ -44,7 +44,7 @@ class ReduceGroupBuilder<T : Any, R : Any>(val actionMeta: Meta) { } } - fun group(groupName: String, filter: (Name, Data<T>) -> Boolean, action: JoinGroup<T, R>.() -> Unit) { + public fun group(groupName: String, filter: (Name, Data<T>) -> Boolean, action: JoinGroup<T, R>.() -> Unit) { groupRules += { node -> listOf( JoinGroup<T, R>(groupName, node.filter(filter)).apply(action) @@ -55,7 +55,7 @@ class ReduceGroupBuilder<T : Any, R : Any>(val actionMeta: Meta) { /** * Apply transformation to the whole node */ - fun result(resultName: String, f: suspend ActionEnv.(Map<Name, T>) -> R) { + public fun result(resultName: String, f: suspend ActionEnv.(Map<Name, T>) -> R) { groupRules += { node -> listOf(JoinGroup<T, R>(resultName, node).apply { result(f) }) } @@ -71,9 +71,9 @@ class ReduceGroupBuilder<T : Any, R : Any>(val actionMeta: Meta) { /** * The same rules as for KPipe */ -class ReduceAction<T : Any, R : Any>( - val inputType: KClass<T>, - val outputType: KClass<out R>, +public class ReduceAction<T : Any, R : Any>( + public val inputType: KClass<T>, + public val outputType: KClass<out R>, private val action: ReduceGroupBuilder<T, R>.() -> Unit ) : Action<T, R> { @@ -104,4 +104,4 @@ class ReduceAction<T : Any, R : Any>( } } -operator fun <T> Map<Name, T>.get(name: String) = get(name.toName()) +public operator fun <T> Map<Name, T>.get(name: String): T? = get(name.toName()) diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/SplitAction.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/SplitAction.kt index dc29394c..731a9403 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/SplitAction.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/SplitAction.kt @@ -10,16 +10,16 @@ import kotlin.collections.set import kotlin.reflect.KClass -class FragmentRule<T : Any, R : Any>(val name: Name, var meta: MetaBuilder) { - lateinit var result: suspend (T) -> R +public class FragmentRule<T : Any, R : Any>(public val name: Name, public var meta: MetaBuilder) { + public lateinit var result: suspend (T) -> R - fun result(f: suspend (T) -> R) { + public fun result(f: suspend (T) -> R) { result = f; } } -class SplitBuilder<T : Any, R : Any>(val name: Name, val meta: Meta) { +public class SplitBuilder<T : Any, R : Any>(public val name: Name, public val meta: Meta) { internal val fragments: MutableMap<Name, FragmentRule<T, R>.() -> Unit> = HashMap() /** @@ -27,14 +27,14 @@ class SplitBuilder<T : Any, R : Any>(val name: Name, val meta: Meta) { * @param name the name of a fragment * @param rule the rule to transform fragment name and meta using */ - fun fragment(name: String, rule: FragmentRule<T, R>.() -> Unit) { + public fun fragment(name: String, rule: FragmentRule<T, R>.() -> Unit) { fragments[name.toName()] = rule } } -class SplitAction<T : Any, R : Any>( - val inputType: KClass<T>, - val outputType: KClass<out R>, +public class SplitAction<T : Any, R : Any>( + public val inputType: KClass<T>, + public val outputType: KClass<out R>, private val action: SplitBuilder<T, R>.() -> Unit ) : Action<T, R> { diff --git a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/dataCast.kt b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/dataCast.kt index 21301dd4..26563bc8 100644 --- a/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/dataCast.kt +++ b/dataforge-data/src/commonMain/kotlin/hep/dataforge/data/dataCast.kt @@ -6,7 +6,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Deferred import kotlin.reflect.KClass -fun <R : Any, T : R> Data<T>.upcast(type: KClass<out R>): Data<R> { +public fun <R : Any, T : R> Data<T>.upcast(type: KClass<out R>): Data<R> { return object : Data<R> by this { override val type: KClass<out R> = type } @@ -15,19 +15,19 @@ fun <R : Any, T : R> Data<T>.upcast(type: KClass<out R>): Data<R> { /** * Safe upcast a [Data] to a supertype */ -inline fun <reified R : Any, T : R> Data<T>.upcast(): Data<R> = upcast(R::class) +public inline fun <reified R : Any, T : R> Data<T>.upcast(): Data<R> = upcast(R::class) /** * Check if node could be safely cast to given class */ -expect fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean +internal expect fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean /** * Check if data could be safely cast to given class */ -expect fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean +internal expect fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean -fun <R : Any> DataItem<*>.canCast(type: KClass<out R>): Boolean = when (this) { +public fun <R : Any> DataItem<*>.canCast(type: KClass<out R>): Boolean = when (this) { is DataItem.Node -> node.canCast(type) is DataItem.Leaf -> data.canCast(type) } @@ -36,7 +36,7 @@ fun <R : Any> DataItem<*>.canCast(type: KClass<out R>): Boolean = when (this) { * Unsafe cast of data node */ @Suppress("UNCHECKED_CAST") -fun <R : Any> Data<*>.cast(type: KClass<out R>): Data<R> { +public fun <R : Any> Data<*>.cast(type: KClass<out R>): Data<R> { return object : Data<R> { override val meta: Meta get() = this@cast.meta override val dependencies: Collection<Goal<*>> get() = this@cast.dependencies @@ -47,10 +47,10 @@ fun <R : Any> Data<*>.cast(type: KClass<out R>): Data<R> { } } -inline fun <reified R : Any> Data<*>.cast(): Data<R> = cast(R::class) +public inline fun <reified R : Any> Data<*>.cast(): Data<R> = cast(R::class) @Suppress("UNCHECKED_CAST") -fun <R : Any> DataNode<*>.cast(type: KClass<out R>): DataNode<R> { +public fun <R : Any> DataNode<*>.cast(type: KClass<out R>): DataNode<R> { return object : DataNode<R> { override val meta: Meta get() = this@cast.meta override val type: KClass<out R> = type @@ -58,12 +58,12 @@ fun <R : Any> DataNode<*>.cast(type: KClass<out R>): DataNode<R> { } } -inline fun <reified R : Any> DataNode<*>.cast(): DataNode<R> = cast(R::class) +public inline fun <reified R : Any> DataNode<*>.cast(): DataNode<R> = cast(R::class) /** * Check that node is compatible with given type meaning that each element could be cast to the type */ -fun <T : Any> DataNode<*>.ensureType(type: KClass<out T>) { +public fun <T : Any> DataNode<*>.ensureType(type: KClass<out T>) { if (!canCast(type)) { error("$type expected, but $type received") } diff --git a/dataforge-data/src/jsMain/kotlin/hep/dataforge/data/dataJS.kt b/dataforge-data/src/jsMain/kotlin/hep/dataforge/data/dataJS.kt index 54148bc5..0257b85a 100644 --- a/dataforge-data/src/jsMain/kotlin/hep/dataforge/data/dataJS.kt +++ b/dataforge-data/src/jsMain/kotlin/hep/dataforge/data/dataJS.kt @@ -5,12 +5,10 @@ import kotlin.reflect.KClass /** * Check that node is compatible with given type meaning that each element could be cast to the type */ -actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean { - //Not supported in js yet - return true +internal actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean { + return this.type == type } -actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean { - //Not supported in js yet - return true +internal actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean { + return this.type == type } diff --git a/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/TypeFilteredDataNode.kt b/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/TypeFilteredDataNode.kt index 3590679c..b67becff 100644 --- a/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/TypeFilteredDataNode.kt +++ b/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/TypeFilteredDataNode.kt @@ -8,7 +8,7 @@ import kotlin.reflect.KClass /** * A zero-copy data node wrapper that returns only children with appropriate type. */ -class TypeFilteredDataNode<out T : Any>(val origin: DataNode<*>, override val type: KClass<out T>) : DataNode<T> { +public class TypeFilteredDataNode<out T : Any>(public val origin: DataNode<*>, override val type: KClass<out T>) : DataNode<T> { override val meta: Meta get() = origin.meta override val items: Map<NameToken, DataItem<T>> by lazy { origin.items.mapNotNull { (key, item) -> diff --git a/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/dataJVM.kt b/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/dataJVM.kt index f354c2f7..6f758dae 100644 --- a/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/dataJVM.kt +++ b/dataforge-data/src/jvmMain/kotlin/hep/dataforge/data/dataJVM.kt @@ -3,33 +3,32 @@ package hep.dataforge.data import kotlinx.coroutines.runBlocking import kotlin.reflect.KClass import kotlin.reflect.full.isSubclassOf -import kotlin.reflect.full.isSuperclassOf /** * Block the thread and get data content */ -fun <T : Any> Data<T>.get(): T = runBlocking { await() } +public fun <T : Any> Data<T>.get(): T = runBlocking { await() } /** * Check that node is compatible with given type meaning that each element could be cast to the type */ -actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean = - type.isSuperclassOf(type) +internal actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean = + type.isSubclassOf(this.type) -actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean = +internal actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean = this.type.isSubclassOf(type) /** * Cast the node to given type if the cast is possible or return null */ -fun <R : Any> Data<*>.filterIsInstance(type: KClass<out R>): Data<R>? = +public fun <R : Any> Data<*>.filterIsInstance(type: KClass<out R>): Data<R>? = if (canCast(type)) cast(type) else null /** * Filter a node by data and node type. Resulting node and its subnodes is guaranteed to have border type [type], * but could contain empty nodes */ -fun <R : Any> DataNode<*>.filterIsInstance(type: KClass<out R>): DataNode<R> { +public fun <R : Any> DataNode<*>.filterIsInstance(type: KClass<out R>): DataNode<R> { return when { canCast(type) -> cast(type) this is TypeFilteredDataNode -> origin.filterIsInstance(type) @@ -40,10 +39,10 @@ fun <R : Any> DataNode<*>.filterIsInstance(type: KClass<out R>): DataNode<R> { /** * Filter all elements of given data item that could be cast to given type. If no elements are available, return null. */ -fun <R : Any> DataItem<*>?.filterIsInstance(type: KClass<out R>): DataItem<R>? = when (this) { +public fun <R : Any> DataItem<*>?.filterIsInstance(type: KClass<out R>): DataItem<R>? = when (this) { null -> null is DataItem.Node -> DataItem.Node(this.node.filterIsInstance(type)) is DataItem.Leaf -> this.data.filterIsInstance(type)?.let { DataItem.Leaf(it) } } -inline fun <reified R : Any> DataItem<*>?.filterIsInstance(): DataItem<R>? = this@filterIsInstance.filterIsInstance(R::class) \ No newline at end of file +public inline fun <reified R : Any> DataItem<*>?.filterIsInstance(): DataItem<R>? = this@filterIsInstance.filterIsInstance(R::class) \ No newline at end of file diff --git a/dataforge-data/src/nativeMain/kotlin/hep/dataforge/data/dataNative.kt b/dataforge-data/src/nativeMain/kotlin/hep/dataforge/data/dataNative.kt new file mode 100644 index 00000000..fe770f88 --- /dev/null +++ b/dataforge-data/src/nativeMain/kotlin/hep/dataforge/data/dataNative.kt @@ -0,0 +1,14 @@ +package hep.dataforge.data + +import kotlin.reflect.KClass + +/** + * Check that node is compatible with given type meaning that each element could be cast to the type + */ +internal actual fun <R : Any> DataNode<*>.canCast(type: KClass<out R>): Boolean { + return this.type == type +} + +internal actual fun <R : Any> Data<*>.canCast(type: KClass<out R>): Boolean { + return this.type == type +} \ No newline at end of file diff --git a/dataforge-io/api/dataforge-io.api b/dataforge-io/api/dataforge-io.api new file mode 100644 index 00000000..1b8f876b --- /dev/null +++ b/dataforge-io/api/dataforge-io.api @@ -0,0 +1,469 @@ +public final class hep/dataforge/io/BinaryMetaFormat : hep/dataforge/io/MetaFormat, hep/dataforge/io/MetaFormatFactory { + public static final field INSTANCE Lhep/dataforge/io/BinaryMetaFormat; + public fun getKey ()S + public fun getName ()Lhep/dataforge/names/Name; + public fun getShortName ()Ljava/lang/String; + public fun getType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/MetaFormat; + public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; + public fun readMeta (Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta; + public final fun readMetaItem (Lkotlinx/io/Input;)Lhep/dataforge/meta/MetaItem; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeMeta (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V + public final fun writeValue (Lkotlinx/io/Output;Lhep/dataforge/values/Value;)V +} + +public final class hep/dataforge/io/BinaryView : kotlinx/io/Binary { + public fun <init> (Lkotlinx/io/Binary;II)V + public fun getSize ()I + public fun read (IILkotlin/jvm/functions/Function1;)Ljava/lang/Object; +} + +public abstract interface class hep/dataforge/io/Consumer { + public abstract fun consume (Lhep/dataforge/io/Envelope;)V +} + +public final class hep/dataforge/io/DoubleIOFormat : hep/dataforge/io/IOFormat, hep/dataforge/io/IOFormatFactory { + public static final field INSTANCE Lhep/dataforge/io/DoubleIOFormat; + public fun getName ()Lhep/dataforge/names/Name; + public fun getType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/IOFormat; + public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; + public fun readObject (Lkotlinx/io/Input;)Ljava/lang/Double; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeObject (Lkotlinx/io/Output;D)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public abstract interface class hep/dataforge/io/Envelope { + public static final field Companion Lhep/dataforge/io/Envelope$Companion; + public abstract fun getData ()Lkotlinx/io/Binary; + public abstract fun getMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/io/Envelope$Companion { + public final fun getENVELOPE_DATA_ID_KEY ()Lhep/dataforge/names/Name; + public final fun getENVELOPE_DATA_TYPE_KEY ()Lhep/dataforge/names/Name; + public final fun getENVELOPE_DESCRIPTION_KEY ()Lhep/dataforge/names/Name; + public final fun getENVELOPE_NAME_KEY ()Lhep/dataforge/names/Name; + public final fun getENVELOPE_NODE_KEY ()Lhep/dataforge/names/Name; + public final fun getENVELOPE_TYPE_KEY ()Lhep/dataforge/names/Name; + public final fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/io/Envelope; +} + +public final class hep/dataforge/io/EnvelopeBuilder : hep/dataforge/io/Envelope { + public fun <init> ()V + public final fun data (Lkotlin/jvm/functions/Function1;)V + public fun getData ()Lkotlinx/io/Binary; + public final fun getDataID ()Ljava/lang/String; + public final fun getDataType ()Ljava/lang/String; + public final fun getDescription ()Ljava/lang/String; + public fun getMeta ()Lhep/dataforge/meta/Meta; + public final fun getName ()Ljava/lang/String; + public final fun getType ()Ljava/lang/String; + public final fun meta (Lkotlin/jvm/functions/Function1;)V + public final fun seal ()Lhep/dataforge/io/Envelope; + public fun setData (Lkotlinx/io/Binary;)V + public final fun setDataID (Ljava/lang/String;)V + public final fun setDataType (Ljava/lang/String;)V + public final fun setDescription (Ljava/lang/String;)V + public fun setMeta (Lhep/dataforge/meta/Meta;)V + public final fun setName (Ljava/lang/String;)V + public final fun setType (Ljava/lang/String;)V +} + +public abstract interface class hep/dataforge/io/EnvelopeFormat : hep/dataforge/io/IOFormat { + public abstract fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory; + public abstract fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope; + public abstract fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope; + public abstract fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V + public abstract fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V +} + +public final class hep/dataforge/io/EnvelopeFormat$DefaultImpls { + public static fun getDefaultMetaFormat (Lhep/dataforge/io/EnvelopeFormat;)Lhep/dataforge/io/MetaFormatFactory; + public static synthetic fun writeEnvelope$default (Lhep/dataforge/io/EnvelopeFormat;Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)V + public static fun writeObject (Lhep/dataforge/io/EnvelopeFormat;Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V +} + +public abstract interface class hep/dataforge/io/EnvelopeFormatFactory : hep/dataforge/io/EnvelopeFormat, hep/dataforge/io/IOFormatFactory { + public static final field Companion Lhep/dataforge/io/EnvelopeFormatFactory$Companion; + public static final field ENVELOPE_FORMAT_TYPE Ljava/lang/String; + public abstract fun getName ()Lhep/dataforge/names/Name; + public abstract fun getType ()Lkotlin/reflect/KClass; + public abstract fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/EnvelopeFormat; + public abstract fun peekFormat (Lhep/dataforge/io/IOPlugin;Lkotlinx/io/Input;)Lhep/dataforge/io/EnvelopeFormat; +} + +public final class hep/dataforge/io/EnvelopeFormatFactory$Companion { + public static final field ENVELOPE_FORMAT_TYPE Ljava/lang/String; +} + +public final class hep/dataforge/io/EnvelopeFormatFactory$DefaultImpls { + public static fun getDefaultMetaFormat (Lhep/dataforge/io/EnvelopeFormatFactory;)Lhep/dataforge/io/MetaFormatFactory; + public static fun getName (Lhep/dataforge/io/EnvelopeFormatFactory;)Lhep/dataforge/names/Name; + public static fun getType (Lhep/dataforge/io/EnvelopeFormatFactory;)Lkotlin/reflect/KClass; + public static fun toMeta (Lhep/dataforge/io/EnvelopeFormatFactory;)Lhep/dataforge/meta/Meta; + public static fun writeObject (Lhep/dataforge/io/EnvelopeFormatFactory;Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V +} + +public final class hep/dataforge/io/EnvelopeFormatKt { + public static final fun read (Lhep/dataforge/io/EnvelopeFormat;Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope; +} + +public final class hep/dataforge/io/EnvelopeKt { + public static final fun contentEquals (Lhep/dataforge/io/Envelope;Lhep/dataforge/io/Envelope;)Z + public static final fun dataEquals (Lhep/dataforge/io/Envelope;Lhep/dataforge/io/Envelope;)Z + public static final fun getDataID (Lhep/dataforge/io/Envelope;)Ljava/lang/String; + public static final fun getDataType (Lhep/dataforge/io/Envelope;)Ljava/lang/String; + public static final fun getDescription (Lhep/dataforge/io/Envelope;)Ljava/lang/String; + public static final fun getType (Lhep/dataforge/io/Envelope;)Ljava/lang/String; + public static final fun metaEquals (Lhep/dataforge/io/Envelope;Lhep/dataforge/io/Envelope;)Z + public static final fun withMetaLayers (Lhep/dataforge/io/Envelope;[Lhep/dataforge/meta/Meta;)Lhep/dataforge/io/Envelope; +} + +public final class hep/dataforge/io/EnvelopePart { + public fun <init> (Lkotlinx/io/Binary;Lhep/dataforge/meta/Meta;)V + public final fun component1 ()Lkotlinx/io/Binary; + public final fun component2 ()Lhep/dataforge/meta/Meta; + public final fun copy (Lkotlinx/io/Binary;Lhep/dataforge/meta/Meta;)Lhep/dataforge/io/EnvelopePart; + public static synthetic fun copy$default (Lhep/dataforge/io/EnvelopePart;Lkotlinx/io/Binary;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/io/EnvelopePart; + public fun equals (Ljava/lang/Object;)Z + public final fun getBinary ()Lkotlinx/io/Binary; + public final fun getDescription ()Lhep/dataforge/meta/Meta; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/io/EnvelopePartsKt { + public static final fun envelope (Lhep/dataforge/io/EnvelopePart;Lhep/dataforge/io/EnvelopeFormat;)Lhep/dataforge/io/Envelope; + public static final fun envelope (Lhep/dataforge/io/EnvelopePart;Lhep/dataforge/io/IOPlugin;)Lhep/dataforge/io/Envelope; + public static final fun envelopes (Lhep/dataforge/io/EnvelopeBuilder;Ljava/util/List;Lhep/dataforge/io/EnvelopeFormat;Ljava/lang/String;)V + public static synthetic fun envelopes$default (Lhep/dataforge/io/EnvelopeBuilder;Ljava/util/List;Lhep/dataforge/io/EnvelopeFormat;Ljava/lang/String;ILjava/lang/Object;)V + public static final fun getName (Lhep/dataforge/io/EnvelopePart;)Ljava/lang/String; + public static final fun multipart (Lhep/dataforge/io/EnvelopeBuilder;Ljava/util/List;Ljava/lang/String;)V + public static synthetic fun multipart$default (Lhep/dataforge/io/EnvelopeBuilder;Ljava/util/List;Ljava/lang/String;ILjava/lang/Object;)V + public static final fun parts (Lhep/dataforge/io/Envelope;)Ljava/util/List; +} + +public final class hep/dataforge/io/FileIOKt { + public static final fun append (Ljava/nio/file/Path;Lkotlin/jvm/functions/Function1;)V + public static final fun getDATA_FILE_NAME (Lhep/dataforge/io/IOPlugin$Companion;)Ljava/lang/String; + public static final fun getMETA_FILE_NAME (Lhep/dataforge/io/IOPlugin$Companion;)Ljava/lang/String; + public static final fun peekBinaryFormat (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;)Lhep/dataforge/io/EnvelopeFormat; + public static final fun read (Ljava/nio/file/Path;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun readEnvelope (Ljava/nio/file/Path;Lhep/dataforge/io/EnvelopeFormat;)Lhep/dataforge/io/Envelope; + public static final fun readEnvelopeFile (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;ZLkotlin/jvm/functions/Function2;)Lhep/dataforge/io/Envelope; + public static synthetic fun readEnvelopeFile$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lhep/dataforge/io/Envelope; + public static final fun readMetaFile (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/MetaFormat;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta; + public static synthetic fun readMetaFile$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/MetaFormat;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)Lhep/dataforge/meta/Meta; + public static final fun rewrite (Ljava/nio/file/Path;Lkotlin/jvm/functions/Function1;)V + public static final fun write (Ljava/nio/file/Path;Lkotlin/jvm/functions/Function1;)V + public static final fun writeEnvelopeDirectory (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;)V + public static synthetic fun writeEnvelopeDirectory$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;ILjava/lang/Object;)V + public static final fun writeEnvelopeFile (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/EnvelopeFormat;Lhep/dataforge/io/MetaFormatFactory;)V + public static synthetic fun writeEnvelopeFile$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/EnvelopeFormat;Lhep/dataforge/io/MetaFormatFactory;ILjava/lang/Object;)V + public static final fun writeMetaFile (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/meta/Meta;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public static synthetic fun writeMetaFile$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/meta/Meta;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)V + public static final fun writeToFile (Lhep/dataforge/io/IOFormat;Ljava/nio/file/Path;Ljava/lang/Object;)V +} + +public abstract interface class hep/dataforge/io/IOFormat : hep/dataforge/meta/MetaRepr { + public static final field Companion Lhep/dataforge/io/IOFormat$Companion; + public abstract fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public abstract fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/IOFormat$Companion { + public final fun getMETA_KEY ()Lhep/dataforge/names/Name; + public final fun getNAME_KEY ()Lhep/dataforge/names/Name; +} + +public abstract interface class hep/dataforge/io/IOFormatFactory : hep/dataforge/context/Factory, hep/dataforge/context/Named, hep/dataforge/meta/MetaRepr { + public static final field Companion Lhep/dataforge/io/IOFormatFactory$Companion; + public static final field IO_FORMAT_TYPE Ljava/lang/String; + public abstract fun getType ()Lkotlin/reflect/KClass; + public abstract fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/io/IOFormatFactory$Companion { + public static final field IO_FORMAT_TYPE Ljava/lang/String; +} + +public final class hep/dataforge/io/IOFormatFactory$DefaultImpls { + public static fun toMeta (Lhep/dataforge/io/IOFormatFactory;)Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/io/IOFormatKt { + public static final fun fill (Lkotlinx/io/pool/ObjectPool;Lkotlin/jvm/functions/Function1;)Ljava/nio/ByteBuffer; + public static final fun readWith (Lkotlinx/io/Binary;Lhep/dataforge/io/IOFormat;)Ljava/lang/Object; + public static final fun readWith (Lkotlinx/io/Input;Lhep/dataforge/io/IOFormat;)Ljava/lang/Object; + public static final fun toBinary (Lhep/dataforge/io/IOFormat;Ljava/lang/Object;)Lkotlinx/io/Binary; + public static final fun writeWith (Lkotlinx/io/Output;Lhep/dataforge/io/IOFormat;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/IOPlugin : hep/dataforge/context/AbstractPlugin { + public static final field Companion Lhep/dataforge/io/IOPlugin$Companion; + public fun <init> (Lhep/dataforge/meta/Meta;)V + public fun content (Ljava/lang/String;)Ljava/util/Map; + public final fun getEnvelopeFormatFactories ()Ljava/util/Collection; + public final fun getIoFormatFactories ()Ljava/util/Collection; + public final fun getMetaFormatFactories ()Ljava/util/Collection; + public fun getTag ()Lhep/dataforge/context/PluginTag; + public final fun resolveEnvelopeFormat (Lhep/dataforge/meta/MetaItem;)Lhep/dataforge/io/EnvelopeFormat; + public final fun resolveIOFormat (Lhep/dataforge/meta/MetaItem;Lkotlin/reflect/KClass;)Lhep/dataforge/io/IOFormat; + public final fun resolveMetaFormat (Ljava/lang/String;Lhep/dataforge/meta/Meta;)Lhep/dataforge/io/MetaFormat; + public final fun resolveMetaFormat (SLhep/dataforge/meta/Meta;)Lhep/dataforge/io/MetaFormat; + public static synthetic fun resolveMetaFormat$default (Lhep/dataforge/io/IOPlugin;Ljava/lang/String;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/io/MetaFormat; + public static synthetic fun resolveMetaFormat$default (Lhep/dataforge/io/IOPlugin;SLhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/io/MetaFormat; +} + +public final class hep/dataforge/io/IOPlugin$Companion : hep/dataforge/context/PluginFactory { + public final fun getDefaultEnvelopeFormats ()Ljava/util/List; + public final fun getDefaultMetaFormats ()Ljava/util/List; + public fun getTag ()Lhep/dataforge/context/PluginTag; + public fun getType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/IOPlugin; + public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; +} + +public final class hep/dataforge/io/IOPluginKt { + public static final fun getIo (Lhep/dataforge/context/Context;)Lhep/dataforge/io/IOPlugin; +} + +public final class hep/dataforge/io/IoMiscKt { + public static final fun Binary (ILkotlin/jvm/functions/Function1;)Lkotlinx/io/Binary; + public static synthetic fun Binary$default (ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlinx/io/Binary; + public static final fun buildByteArray (ILkotlin/jvm/functions/Function1;)[B + public static synthetic fun buildByteArray$default (ILkotlin/jvm/functions/Function1;ILjava/lang/Object;)[B + public static final fun get (Lkotlinx/io/Binary;Lkotlin/ranges/IntRange;)Lhep/dataforge/io/BinaryView; + public static final fun readRawString (Lkotlinx/io/Input;I)Ljava/lang/String; + public static final fun view (Lkotlinx/io/Binary;II)Lhep/dataforge/io/BinaryView; + public static final fun writeRawString (Lkotlinx/io/Output;Ljava/lang/String;)V +} + +public final class hep/dataforge/io/JsonMetaFormat : hep/dataforge/io/MetaFormat { + public static final field Companion Lhep/dataforge/io/JsonMetaFormat$Companion; + public fun <init> ()V + public fun <init> (Lkotlinx/serialization/json/Json;)V + public synthetic fun <init> (Lkotlinx/serialization/json/Json;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun readMeta (Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeMeta (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/JsonMetaFormat$Companion : hep/dataforge/io/MetaFormatFactory { + public final fun getDEFAULT_JSON ()Lkotlinx/serialization/json/Json; + public fun getKey ()S + public fun getName ()Lhep/dataforge/names/Name; + public fun getShortName ()Ljava/lang/String; + public fun getType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/MetaFormat; + public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; + public fun readMeta (Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeMeta (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/ListIOFormat : hep/dataforge/io/IOFormat { + public fun <init> (Lhep/dataforge/io/IOFormat;)V + public final fun getFormat ()Lhep/dataforge/io/IOFormat; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun readObject (Lkotlinx/io/Input;)Ljava/util/List; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V + public fun writeObject (Lkotlinx/io/Output;Ljava/util/List;)V +} + +public abstract interface class hep/dataforge/io/MetaFormat : hep/dataforge/io/IOFormat { + public abstract fun readMeta (Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta; + public abstract fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta; + public abstract fun writeMeta (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public abstract fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V +} + +public final class hep/dataforge/io/MetaFormat$DefaultImpls { + public static synthetic fun readMeta$default (Lhep/dataforge/io/MetaFormat;Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)Lhep/dataforge/meta/Meta; + public static fun readObject (Lhep/dataforge/io/MetaFormat;Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta; + public static synthetic fun writeMeta$default (Lhep/dataforge/io/MetaFormat;Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)V + public static fun writeObject (Lhep/dataforge/io/MetaFormat;Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V +} + +public abstract interface class hep/dataforge/io/MetaFormatFactory : hep/dataforge/io/IOFormatFactory, hep/dataforge/io/MetaFormat { + public static final field Companion Lhep/dataforge/io/MetaFormatFactory$Companion; + public static final field META_FORMAT_TYPE Ljava/lang/String; + public abstract fun getKey ()S + public abstract fun getName ()Lhep/dataforge/names/Name; + public abstract fun getShortName ()Ljava/lang/String; + public abstract fun getType ()Lkotlin/reflect/KClass; + public abstract fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/MetaFormat; +} + +public final class hep/dataforge/io/MetaFormatFactory$Companion { + public static final field META_FORMAT_TYPE Ljava/lang/String; +} + +public final class hep/dataforge/io/MetaFormatFactory$DefaultImpls { + public static fun getKey (Lhep/dataforge/io/MetaFormatFactory;)S + public static fun getName (Lhep/dataforge/io/MetaFormatFactory;)Lhep/dataforge/names/Name; + public static fun getType (Lhep/dataforge/io/MetaFormatFactory;)Lkotlin/reflect/KClass; + public static fun readObject (Lhep/dataforge/io/MetaFormatFactory;Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta; + public static fun toMeta (Lhep/dataforge/io/MetaFormatFactory;)Lhep/dataforge/meta/Meta; + public static fun writeObject (Lhep/dataforge/io/MetaFormatFactory;Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V +} + +public final class hep/dataforge/io/MetaFormatKt { + public static final fun parse (Lhep/dataforge/io/MetaFormat;Ljava/lang/String;)Lhep/dataforge/meta/Meta; + public static final fun parse (Lhep/dataforge/io/MetaFormatFactory;Ljava/lang/String;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Meta; + public static final fun toString (Lhep/dataforge/meta/Meta;Lhep/dataforge/io/MetaFormat;)Ljava/lang/String; + public static final fun toString (Lhep/dataforge/meta/Meta;Lhep/dataforge/io/MetaFormatFactory;)Ljava/lang/String; +} + +public final class hep/dataforge/io/PartialEnvelope { + public synthetic fun <init> (Lhep/dataforge/meta/Meta;ILkotlin/ULong;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Lhep/dataforge/meta/Meta; + public final fun component2-pVg5ArA ()I + public final fun component3-6VbMDqA ()Lkotlin/ULong; + public final fun copy-BMK4sig (Lhep/dataforge/meta/Meta;ILkotlin/ULong;)Lhep/dataforge/io/PartialEnvelope; + public static synthetic fun copy-BMK4sig$default (Lhep/dataforge/io/PartialEnvelope;Lhep/dataforge/meta/Meta;ILkotlin/ULong;ILjava/lang/Object;)Lhep/dataforge/io/PartialEnvelope; + public fun equals (Ljava/lang/Object;)Z + public final fun getDataOffset-pVg5ArA ()I + public final fun getDataSize-6VbMDqA ()Lkotlin/ULong; + public final fun getMeta ()Lhep/dataforge/meta/Meta; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/io/ProxyEnvelope : hep/dataforge/io/Envelope { + public fun <init> (Lhep/dataforge/io/Envelope;[Lhep/dataforge/meta/Meta;)V + public fun getData ()Lkotlinx/io/Binary; + public fun getMeta ()Lhep/dataforge/meta/Laminate; + public synthetic fun getMeta ()Lhep/dataforge/meta/Meta; + public final fun getSource ()Lhep/dataforge/io/Envelope; +} + +public abstract interface class hep/dataforge/io/Responder { + public abstract fun respond (Lhep/dataforge/io/Envelope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class hep/dataforge/io/SimpleEnvelope : hep/dataforge/io/Envelope { + public fun <init> (Lhep/dataforge/meta/Meta;Lkotlinx/io/Binary;)V + public fun getData ()Lkotlinx/io/Binary; + public fun getMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/io/StreamsIOKt { + public static final fun read (Ljava/io/InputStream;ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun read (Ljava/io/InputStream;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun readBlocking (Ljava/io/InputStream;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun write (Ljava/io/OutputStream;Lkotlin/jvm/functions/Function1;)V +} + +public final class hep/dataforge/io/TaggedEnvelopeFormat : hep/dataforge/io/EnvelopeFormat { + public static final field Companion Lhep/dataforge/io/TaggedEnvelopeFormat$Companion; + public fun <init> (Lhep/dataforge/io/IOPlugin;Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION;)V + public synthetic fun <init> (Lhep/dataforge/io/IOPlugin;Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory; + public final fun getIo ()Lhep/dataforge/io/IOPlugin; + public final fun getVersion ()Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/TaggedEnvelopeFormat$Companion : hep/dataforge/io/EnvelopeFormatFactory { + public fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory; + public fun getName ()Lhep/dataforge/names/Name; + public fun getType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/EnvelopeFormat; + public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; + public fun peekFormat (Lhep/dataforge/io/IOPlugin;Lkotlinx/io/Input;)Lhep/dataforge/io/EnvelopeFormat; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/TaggedEnvelopeFormat$VERSION : java/lang/Enum { + public static final field DF02 Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION; + public static final field DF03 Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION; + public final fun getTagSize-pVg5ArA ()I + public static fun valueOf (Ljava/lang/String;)Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION; + public static fun values ()[Lhep/dataforge/io/TaggedEnvelopeFormat$VERSION; +} + +public final class hep/dataforge/io/TaglessEnvelopeFormat : hep/dataforge/io/EnvelopeFormat { + public static final field Companion Lhep/dataforge/io/TaglessEnvelopeFormat$Companion; + public static final field DATA_LENGTH_PROPERTY Ljava/lang/String; + public static final field DATA_START_PROPERTY Ljava/lang/String; + public static final field DEFAULT_DATA_START Ljava/lang/String; + public static final field DEFAULT_META_START Ljava/lang/String; + public static final field META_LENGTH_PROPERTY Ljava/lang/String; + public static final field META_START_PROPERTY Ljava/lang/String; + public static final field META_TYPE_PROPERTY Ljava/lang/String; + public static final field TAGLESS_ENVELOPE_HEADER Ljava/lang/String; + public static final field TAGLESS_ENVELOPE_TYPE Ljava/lang/String; + public static final field code I + public fun <init> (Lhep/dataforge/io/IOPlugin;Lhep/dataforge/meta/Meta;)V + public synthetic fun <init> (Lhep/dataforge/io/IOPlugin;Lhep/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory; + public final fun getIo ()Lhep/dataforge/io/IOPlugin; + public final fun getMeta ()Lhep/dataforge/meta/Meta; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/TaglessEnvelopeFormat$Companion : hep/dataforge/io/EnvelopeFormatFactory { + public fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory; + public fun getName ()Lhep/dataforge/names/Name; + public fun getType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/EnvelopeFormat; + public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; + public fun peekFormat (Lhep/dataforge/io/IOPlugin;Lkotlinx/io/Input;)Lhep/dataforge/io/EnvelopeFormat; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/ValueIOFormat : hep/dataforge/io/IOFormat, hep/dataforge/io/IOFormatFactory { + public static final field INSTANCE Lhep/dataforge/io/ValueIOFormat; + public fun getName ()Lhep/dataforge/names/Name; + public fun getType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/IOFormat; + public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/values/Value; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/values/Value;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + diff --git a/dataforge-io/build.gradle.kts b/dataforge-io/build.gradle.kts index 15439cd4..d2e3a41a 100644 --- a/dataforge-io/build.gradle.kts +++ b/dataforge-io/build.gradle.kts @@ -1,17 +1,17 @@ -import scientifik.DependencySourceSet.TEST -import scientifik.useSerialization - plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") + id("ru.mipt.npm.native") } description = "IO module" -useSerialization(sourceSet = TEST){ - cbor() +kscience { + useSerialization(sourceSet = ru.mipt.npm.gradle.DependencySourceSet.TEST) { + cbor() + } } -val ioVersion by rootProject.extra("0.2.0-npm-dev-7") +val ioVersion by rootProject.extra("0.2.0-npm-dev-11") kotlin { sourceSets { diff --git a/dataforge-io/dataforge-io-yaml/api/dataforge-io-yaml.api b/dataforge-io/dataforge-io-yaml/api/dataforge-io-yaml.api new file mode 100644 index 00000000..de7b3ab2 --- /dev/null +++ b/dataforge-io/dataforge-io-yaml/api/dataforge-io-yaml.api @@ -0,0 +1,59 @@ +public final class hep/dataforge/io/yaml/FrontMatterEnvelopeFormat : hep/dataforge/io/EnvelopeFormat { + public static final field Companion Lhep/dataforge/io/yaml/FrontMatterEnvelopeFormat$Companion; + public static final field SEPARATOR Ljava/lang/String; + public fun <init> (Lhep/dataforge/io/IOPlugin;Lhep/dataforge/meta/Meta;)V + public synthetic fun <init> (Lhep/dataforge/io/IOPlugin;Lhep/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/yaml/FrontMatterEnvelopeFormat$Companion : hep/dataforge/io/EnvelopeFormatFactory { + public fun getDefaultMetaFormat ()Lhep/dataforge/io/MetaFormatFactory; + public fun getName ()Lhep/dataforge/names/Name; + public fun getType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/EnvelopeFormat; + public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; + public fun peekFormat (Lhep/dataforge/io/IOPlugin;Lkotlinx/io/Input;)Lhep/dataforge/io/EnvelopeFormat; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/io/Envelope; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun readPartial (Lkotlinx/io/Input;)Lhep/dataforge/io/PartialEnvelope; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeEnvelope (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;Lhep/dataforge/io/MetaFormatFactory;Lhep/dataforge/meta/Meta;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/io/Envelope;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/yaml/YamlMetaFormat : hep/dataforge/io/MetaFormat { + public static final field Companion Lhep/dataforge/io/yaml/YamlMetaFormat$Companion; + public fun <init> (Lhep/dataforge/meta/Meta;)V + public fun readMeta (Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeMeta (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + +public final class hep/dataforge/io/yaml/YamlMetaFormat$Companion : hep/dataforge/io/MetaFormatFactory { + public fun getKey ()S + public fun getName ()Lhep/dataforge/names/Name; + public fun getShortName ()Ljava/lang/String; + public fun getType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/io/MetaFormat; + public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; + public fun readMeta (Lkotlinx/io/Input;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta; + public fun readObject (Lkotlinx/io/Input;)Lhep/dataforge/meta/Meta; + public synthetic fun readObject (Lkotlinx/io/Input;)Ljava/lang/Object; + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun writeMeta (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public fun writeObject (Lkotlinx/io/Output;Lhep/dataforge/meta/Meta;)V + public synthetic fun writeObject (Lkotlinx/io/Output;Ljava/lang/Object;)V +} + diff --git a/dataforge-io/dataforge-io-yaml/build.gradle.kts b/dataforge-io/dataforge-io-yaml/build.gradle.kts index f29bff4a..720e1fba 100644 --- a/dataforge-io/dataforge-io-yaml/build.gradle.kts +++ b/dataforge-io/dataforge-io-yaml/build.gradle.kts @@ -1,13 +1,13 @@ -import scientifik.useSerialization - plugins { - id("scientifik.jvm") + id("ru.mipt.npm.jvm") } description = "YAML meta IO" -useSerialization{ - yaml() +kscience { + useSerialization { + yaml() + } } dependencies { diff --git a/dataforge-io/dataforge-io-yaml/src/main/kotlin/hep/dataforge/io/yaml/FrontMatterEnvelopeFormat.kt b/dataforge-io/dataforge-io-yaml/src/main/kotlin/hep/dataforge/io/yaml/FrontMatterEnvelopeFormat.kt index 0fffdb7e..aa2537be 100644 --- a/dataforge-io/dataforge-io-yaml/src/main/kotlin/hep/dataforge/io/yaml/FrontMatterEnvelopeFormat.kt +++ b/dataforge-io/dataforge-io-yaml/src/main/kotlin/hep/dataforge/io/yaml/FrontMatterEnvelopeFormat.kt @@ -9,20 +9,19 @@ import hep.dataforge.meta.Meta import kotlinx.io.* import kotlinx.io.text.readUtf8Line import kotlinx.io.text.writeUtf8String -import kotlinx.serialization.toUtf8Bytes @DFExperimental -class FrontMatterEnvelopeFormat( - val io: IOPlugin, - val meta: Meta = Meta.EMPTY +public class FrontMatterEnvelopeFormat( + private val io: IOPlugin, + private val meta: Meta = Meta.EMPTY, ) : EnvelopeFormat { - override fun Input.readPartial(): PartialEnvelope { - var line: String = "" + override fun readPartial(input: Input): PartialEnvelope { + var line = "" var offset = 0u do { - line = readUtf8Line() //?: error("Input does not contain front matter separator") - offset += line.toUtf8Bytes().size.toUInt() + line = input.readUtf8Line() //?: error("Input does not contain front matter separator") + offset += line.toByteArray().size.toUInt() } while (!line.startsWith(SEPARATOR)) val readMetaFormat = @@ -32,22 +31,21 @@ class FrontMatterEnvelopeFormat( //TODO replace by preview val meta = Binary { do { - line = readUtf8Line() + line = input.readUtf8Line() writeUtf8String(line + "\r\n") - offset += line.toUtf8Bytes().size.toUInt() + offset += line.toByteArray().size.toUInt() } while (!line.startsWith(SEPARATOR)) }.read { - readMetaFormat.run { - readMeta() - } + readMetaFormat.readMeta(input) + } return PartialEnvelope(meta, offset, null) } - override fun Input.readObject(): Envelope { - var line: String = "" + override fun readObject(input: Input): Envelope { + var line = "" do { - line = readUtf8Line() //?: error("Input does not contain front matter separator") + line = input.readUtf8Line() //?: error("Input does not contain front matter separator") } while (!line.startsWith(SEPARATOR)) val readMetaFormat = @@ -56,26 +54,29 @@ class FrontMatterEnvelopeFormat( val meta = Binary { do { - writeUtf8String(readUtf8Line() + "\r\n") + writeUtf8String(input.readUtf8Line() + "\r\n") } while (!line.startsWith(SEPARATOR)) }.read { - readMetaFormat.run { - readMeta() - } + readMetaFormat.readMeta(input) } - val bytes = readByteArray() + val bytes = input.readByteArray() val data = bytes.asBinary() return SimpleEnvelope(meta, data) } - override fun Output.writeEnvelope(envelope: Envelope, metaFormatFactory: MetaFormatFactory, formatMeta: Meta) { - val metaFormat = metaFormatFactory(formatMeta, io.context) - writeRawString("$SEPARATOR\r\n") - metaFormat.run { writeObject(envelope.meta) } - writeRawString("$SEPARATOR\r\n") + override fun writeEnvelope( + output: Output, + envelope: Envelope, + metaFormatFactory: MetaFormatFactory, + formatMeta: Meta, + ) { + val metaFormat = metaFormatFactory(formatMeta, this@FrontMatterEnvelopeFormat.io.context) + output.writeRawString("${hep.dataforge.io.yaml.FrontMatterEnvelopeFormat.Companion.SEPARATOR}\r\n") + metaFormat.run { this.writeObject(output, envelope.meta) } + output.writeRawString("${hep.dataforge.io.yaml.FrontMatterEnvelopeFormat.Companion.SEPARATOR}\r\n") //Printing data envelope.data?.let { data -> - writeBinary(data) + output.writeBinary(data) } } @@ -84,8 +85,8 @@ class FrontMatterEnvelopeFormat( META_KEY put meta } - companion object : EnvelopeFormatFactory { - const val SEPARATOR = "---" + public companion object : EnvelopeFormatFactory { + public const val SEPARATOR = "---" private val metaTypeRegex = "---(\\w*)\\s*".toRegex() @@ -106,14 +107,18 @@ class FrontMatterEnvelopeFormat( private val default by lazy { invoke() } - override fun Input.readPartial(): PartialEnvelope = - default.run { readPartial() } + override fun readPartial(input: Input): PartialEnvelope = + default.readPartial(input) - override fun Output.writeEnvelope(envelope: Envelope, metaFormatFactory: MetaFormatFactory, formatMeta: Meta) = - default.run { writeEnvelope(envelope, metaFormatFactory, formatMeta) } + override fun writeEnvelope( + output: Output, + envelope: Envelope, + metaFormatFactory: MetaFormatFactory, + formatMeta: Meta, + ): Unit = default.writeEnvelope(output, envelope, metaFormatFactory, formatMeta) - override fun Input.readObject(): Envelope = - default.run { readObject() } + + override fun readObject(input: Input): Envelope = default.readObject(input) } } \ No newline at end of file diff --git a/dataforge-io/dataforge-io-yaml/src/main/kotlin/hep/dataforge/io/yaml/YamlMetaFormat.kt b/dataforge-io/dataforge-io-yaml/src/main/kotlin/hep/dataforge/io/yaml/YamlMetaFormat.kt index 5806abf8..18e8af06 100644 --- a/dataforge-io/dataforge-io-yaml/src/main/kotlin/hep/dataforge/io/yaml/YamlMetaFormat.kt +++ b/dataforge-io/dataforge-io-yaml/src/main/kotlin/hep/dataforge/io/yaml/YamlMetaFormat.kt @@ -16,17 +16,20 @@ import kotlinx.io.asInputStream import kotlinx.io.text.writeUtf8String import org.yaml.snakeyaml.Yaml +/** + * Represent meta as Yaml + */ @DFExperimental -class YamlMetaFormat(val meta: Meta) : MetaFormat { +public class YamlMetaFormat(private val meta: Meta) : MetaFormat { private val yaml = Yaml() - override fun Output.writeMeta(meta: Meta, descriptor: NodeDescriptor?) { + override fun writeMeta(output: Output, meta: Meta, descriptor: NodeDescriptor?) { val string = yaml.dump(meta.toMap(descriptor)) - writeUtf8String(string) + output.writeUtf8String(string) } - override fun Input.readMeta(descriptor: NodeDescriptor?): Meta { - val map: Map<String, Any?> = yaml.load(asInputStream()) + override fun readMeta(input: Input, descriptor: NodeDescriptor?): Meta { + val map: Map<String, Any?> = yaml.load(input.asInputStream()) return map.toMeta(descriptor) } @@ -35,19 +38,19 @@ class YamlMetaFormat(val meta: Meta) : MetaFormat { META_KEY put meta } - companion object : MetaFormatFactory { + public companion object : MetaFormatFactory { override fun invoke(meta: Meta, context: Context): MetaFormat = YamlMetaFormat(meta) - override val shortName = "yaml" + override val shortName: String = "yaml" override val key: Short = 0x594d //YM private val default = YamlMetaFormat() - override fun Output.writeMeta(meta: Meta, descriptor: NodeDescriptor?) = - default.run { writeMeta(meta, descriptor) } + override fun writeMeta(output: Output, meta: Meta, descriptor: NodeDescriptor?): Unit = + default.writeMeta(output, meta, descriptor) - override fun Input.readMeta(descriptor: NodeDescriptor?): Meta = - default.run { readMeta(descriptor) } + override fun readMeta(input: kotlinx.io.Input, descriptor: NodeDescriptor?): Meta = + default.readMeta(input, descriptor) } } \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/BinaryMetaFormat.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/BinaryMetaFormat.kt index e753b56c..547d567c 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/BinaryMetaFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/BinaryMetaFormat.kt @@ -11,14 +11,18 @@ import kotlinx.io.* import kotlinx.io.text.readUtf8String import kotlinx.io.text.writeUtf8String -object BinaryMetaFormat : MetaFormat, MetaFormatFactory { +/** + * A DataForge-specific simplified binary format for meta + * TODO add description + */ +public object BinaryMetaFormat : MetaFormat, MetaFormatFactory { override val shortName: String = "bin" override val key: Short = 0x4249//BI override fun invoke(meta: Meta, context: Context): MetaFormat = this - override fun Input.readMeta(descriptor: NodeDescriptor?): Meta { - return (readMetaItem() as MetaItem.NodeItem).node + override fun readMeta(input: Input, descriptor: NodeDescriptor?): Meta { + return (input.readMetaItem() as MetaItem.NodeItem).node } private fun Output.writeChar(char: Char) = writeByte(char.toByte()) @@ -28,7 +32,7 @@ object BinaryMetaFormat : MetaFormat, MetaFormatFactory { writeUtf8String(str) } - fun Output.writeValue(value: Value) { + public fun Output.writeValue(value: Value) { if (value.isList()) { writeChar('L') writeInt(value.list.size) @@ -75,17 +79,21 @@ object BinaryMetaFormat : MetaFormat, MetaFormatFactory { } } - override fun Output.writeMeta(meta: Meta, descriptor: NodeDescriptor?) { - writeChar('M') - writeInt(meta.items.size) + override fun writeMeta( + output: kotlinx.io.Output, + meta: hep.dataforge.meta.Meta, + descriptor: hep.dataforge.meta.descriptors.NodeDescriptor? + ) { + output.writeChar('M') + output.writeInt(meta.items.size) meta.items.forEach { (key, item) -> - writeString(key.toString()) + output.writeString(key.toString()) when (item) { is MetaItem.ValueItem -> { - writeValue(item.value) + output.writeValue(item.value) } is MetaItem.NodeItem -> { - writeObject(item.node) + writeObject(output, item.node) } } } @@ -97,7 +105,7 @@ object BinaryMetaFormat : MetaFormat, MetaFormatFactory { } @Suppress("UNCHECKED_CAST") - fun Input.readMetaItem(): MetaItem<MetaBuilder> { + public fun Input.readMetaItem(): MetaItem<MetaBuilder> { return when (val keyChar = readByte().toChar()) { 'S' -> MetaItem.ValueItem(StringValue(readString())) 'N' -> MetaItem.ValueItem(Null) diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Consumer.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Consumer.kt new file mode 100644 index 00000000..0ef5d327 --- /dev/null +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Consumer.kt @@ -0,0 +1,11 @@ +package hep.dataforge.io + +import hep.dataforge.meta.DFExperimental + +/** + * A fire-and-forget consumer of messages + */ +@DFExperimental +public interface Consumer { + public fun consume(message: Envelope): Unit +} \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Envelope.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Envelope.kt index d7c60116..992a080f 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Envelope.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Envelope.kt @@ -4,64 +4,66 @@ import hep.dataforge.meta.Laminate import hep.dataforge.meta.Meta import hep.dataforge.meta.get import hep.dataforge.meta.string +import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.names.plus import kotlinx.io.Binary -interface Envelope { - val meta: Meta - val data: Binary? +public interface Envelope { + public val meta: Meta + public val data: Binary? - companion object { + public companion object { /** * meta keys */ - val ENVELOPE_NODE_KEY = "@envelope".asName() - val ENVELOPE_TYPE_KEY = ENVELOPE_NODE_KEY + "type" - val ENVELOPE_DATA_TYPE_KEY = ENVELOPE_NODE_KEY + "dataType" - val ENVELOPE_DATA_ID_KEY = ENVELOPE_NODE_KEY + "dataID" - val ENVELOPE_DESCRIPTION_KEY = ENVELOPE_NODE_KEY + "description" - val ENVELOPE_NAME_KEY = ENVELOPE_NODE_KEY + "name" + public val ENVELOPE_NODE_KEY: Name = "@envelope".asName() + public val ENVELOPE_TYPE_KEY: Name = ENVELOPE_NODE_KEY + "type" + public val ENVELOPE_DATA_TYPE_KEY: Name = ENVELOPE_NODE_KEY + "dataType" + public val ENVELOPE_DATA_ID_KEY: Name = ENVELOPE_NODE_KEY + "dataID" + public val ENVELOPE_DESCRIPTION_KEY: Name = ENVELOPE_NODE_KEY + "description" + public val ENVELOPE_NAME_KEY: Name = ENVELOPE_NODE_KEY + "name" //const val ENVELOPE_TIME_KEY = "@envelope.time" /** * Build a static envelope using provided builder */ - inline operator fun invoke(block: EnvelopeBuilder.() -> Unit) = EnvelopeBuilder().apply(block).build() + public inline operator fun invoke(block: EnvelopeBuilder.() -> Unit): Envelope = + EnvelopeBuilder().apply(block).seal() } } -class SimpleEnvelope(override val meta: Meta, override val data: Binary?) : Envelope +public class SimpleEnvelope(override val meta: Meta, override val data: Binary?) : Envelope /** * The purpose of the envelope * */ -val Envelope.type: String? get() = meta[Envelope.ENVELOPE_TYPE_KEY].string +public val Envelope.type: String? get() = meta[Envelope.ENVELOPE_TYPE_KEY].string /** * The type of data encoding * */ -val Envelope.dataType: String? get() = meta[Envelope.ENVELOPE_DATA_TYPE_KEY].string +public val Envelope.dataType: String? get() = meta[Envelope.ENVELOPE_DATA_TYPE_KEY].string /** * Textual user friendly description * */ -val Envelope.description: String? get() = meta[Envelope.ENVELOPE_DESCRIPTION_KEY].string +public val Envelope.description: String? get() = meta[Envelope.ENVELOPE_DESCRIPTION_KEY].string /** * An optional unique identifier that is used for data comparison. Data without identifier could not be compared to another data. */ -val Envelope.dataID: String? get() = meta[Envelope.ENVELOPE_DATA_ID_KEY].string +public val Envelope.dataID: String? get() = meta[Envelope.ENVELOPE_DATA_ID_KEY].string -fun Envelope.metaEquals(other: Envelope): Boolean = this.meta == other.meta +public fun Envelope.metaEquals(other: Envelope): Boolean = this.meta == other.meta -fun Envelope.dataEquals(other: Envelope): Boolean = this.dataID != null && this.dataID == other.dataID +public fun Envelope.dataEquals(other: Envelope): Boolean = this.dataID != null && this.dataID == other.dataID -fun Envelope.contentEquals(other: Envelope): Boolean { +public fun Envelope.contentEquals(other: Envelope): Boolean { return (this === other || (metaEquals(other) && dataEquals(other))) } @@ -69,7 +71,7 @@ fun Envelope.contentEquals(other: Envelope): Boolean { /** * An envelope, which wraps existing envelope and adds one or several additional layers of meta */ -class ProxyEnvelope(val source: Envelope, vararg meta: Meta) : Envelope { +public class ProxyEnvelope(public val source: Envelope, vararg meta: Meta) : Envelope { override val meta: Laminate = Laminate(*meta, source.meta) override val data: Binary? get() = source.data } @@ -77,7 +79,7 @@ class ProxyEnvelope(val source: Envelope, vararg meta: Meta) : Envelope { /** * Add few meta layers to existing envelope (on top of existing meta) */ -fun Envelope.withMetaLayers(vararg layers: Meta): Envelope { +public fun Envelope.withMetaLayers(vararg layers: Meta): Envelope { return when { layers.isEmpty() -> this this is ProxyEnvelope -> ProxyEnvelope(source, *layers, *this.meta.layers.toTypedArray()) diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeBuilder.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeBuilder.kt index c37f7c38..73775af3 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeBuilder.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeBuilder.kt @@ -3,42 +3,44 @@ package hep.dataforge.io import hep.dataforge.meta.* import kotlinx.io.* -class EnvelopeBuilder { +public class EnvelopeBuilder : Envelope { private val metaBuilder = MetaBuilder() - var data: Binary? = null - fun meta(block: MetaBuilder.() -> Unit) { + override var data: Binary? = null + override var meta: Meta + get() = metaBuilder + set(value) { + metaBuilder.update(value) + } + + public fun meta(block: MetaBuilder.() -> Unit) { metaBuilder.apply(block) } - fun meta(meta: Meta) { - metaBuilder.update(meta) - } - /** * The general purpose of the envelope */ - var type by metaBuilder.string(key = Envelope.ENVELOPE_TYPE_KEY) - var dataType by metaBuilder.string(key = Envelope.ENVELOPE_DATA_TYPE_KEY) + public var type: String? by metaBuilder.string(key = Envelope.ENVELOPE_TYPE_KEY) + public var dataType: String? by metaBuilder.string(key = Envelope.ENVELOPE_DATA_TYPE_KEY) /** * Data unique identifier to bypass identity checks */ - var dataID by metaBuilder.string(key = Envelope.ENVELOPE_DATA_ID_KEY) - var description by metaBuilder.string(key = Envelope.ENVELOPE_DESCRIPTION_KEY) - var name by metaBuilder.string(key = Envelope.ENVELOPE_NAME_KEY) + public var dataID: String? by metaBuilder.string(key = Envelope.ENVELOPE_DATA_ID_KEY) + public var description: String? by metaBuilder.string(key = Envelope.ENVELOPE_DESCRIPTION_KEY) + public var name: String? by metaBuilder.string(key = Envelope.ENVELOPE_NAME_KEY) /** * Construct a data binary from given builder */ @OptIn(ExperimentalIoApi::class) - fun data(block: Output.() -> Unit) { + public fun data(block: Output.() -> Unit) { val arrayBuilder = ByteArrayOutput() arrayBuilder.block() data = arrayBuilder.toByteArray().asBinary() } - fun build() = SimpleEnvelope(metaBuilder.seal(), data) + public fun seal(): Envelope = SimpleEnvelope(metaBuilder.seal(), data) } diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeFormat.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeFormat.kt index 9b819a97..b02052c1 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeFormat.kt @@ -13,31 +13,29 @@ import kotlin.reflect.KClass /** * A partially read envelope with meta, but without data */ -@ExperimentalUnsignedTypes -data class PartialEnvelope(val meta: Meta, val dataOffset: UInt, val dataSize: ULong?) +public data class PartialEnvelope(val meta: Meta, val dataOffset: UInt, val dataSize: ULong?) -interface EnvelopeFormat : IOFormat<Envelope> { - val defaultMetaFormat: MetaFormatFactory get() = JsonMetaFormat +public interface EnvelopeFormat : IOFormat<Envelope> { + public val defaultMetaFormat: MetaFormatFactory get() = JsonMetaFormat - fun Input.readPartial(): PartialEnvelope + public fun readPartial(input: Input): PartialEnvelope - fun Output.writeEnvelope( + public fun writeEnvelope( + output: Output, envelope: Envelope, metaFormatFactory: MetaFormatFactory = defaultMetaFormat, - formatMeta: Meta = Meta.EMPTY + formatMeta: Meta = Meta.EMPTY, ) - override fun Input.readObject(): Envelope + override fun readObject(input: Input): Envelope - override fun Output.writeObject(obj: Envelope): Unit = writeEnvelope(obj) + override fun writeObject(output: Output, obj: Envelope): Unit = writeEnvelope(output, obj) } -fun EnvelopeFormat.readPartial(input: Input) = input.readPartial() - -fun EnvelopeFormat.read(input: Input) = input.readObject() +public fun EnvelopeFormat.read(input: Input): Envelope = readObject(input) @Type(ENVELOPE_FORMAT_TYPE) -interface EnvelopeFormatFactory : IOFormatFactory<Envelope>, EnvelopeFormat { +public interface EnvelopeFormatFactory : IOFormatFactory<Envelope>, EnvelopeFormat { override val name: Name get() = "envelope".asName() override val type: KClass<out Envelope> get() = Envelope::class @@ -47,9 +45,9 @@ interface EnvelopeFormatFactory : IOFormatFactory<Envelope>, EnvelopeFormat { * Try to infer specific format from input and return null if the attempt is failed. * This method does **not** return Input into initial state. */ - fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat? + public fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat? - companion object { - const val ENVELOPE_FORMAT_TYPE = "io.format.envelope" + public companion object { + public const val ENVELOPE_FORMAT_TYPE: String = "io.format.envelope" } } \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeParts.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeParts.kt index 19ccb458..cae87229 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeParts.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/EnvelopeParts.kt @@ -31,11 +31,11 @@ private class PartDescriptor : Scheme() { } } -data class EnvelopePart(val binary: Binary, val description: Meta?) +public data class EnvelopePart(val binary: Binary, val description: Meta?) -typealias EnvelopeParts = List<EnvelopePart> +public typealias EnvelopeParts = List<EnvelopePart> -fun EnvelopeBuilder.multipart( +public fun EnvelopeBuilder.multipart( parts: EnvelopeParts, separator: String = DEFAULT_MULTIPART_DATA_SEPARATOR ) { @@ -69,7 +69,7 @@ fun EnvelopeBuilder.multipart( } } -fun EnvelopeBuilder.envelopes( +public fun EnvelopeBuilder.envelopes( envelopes: List<Envelope>, format: EnvelopeFormat = TaggedEnvelopeFormat, separator: String = DEFAULT_MULTIPART_DATA_SEPARATOR @@ -84,11 +84,11 @@ fun EnvelopeBuilder.envelopes( multipart(parts, separator) } -fun Envelope.parts(): EnvelopeParts { +public fun Envelope.parts(): EnvelopeParts { if (data == null) return emptyList() //TODO add zip folder reader val parts = meta.getIndexed(PARTS_KEY).values.mapNotNull { it.node }.map { - PartDescriptor.wrap(it) + PartDescriptor.read(it) } return if (parts.isEmpty()) { listOf(EnvelopePart(data!!, meta[MULTIPART_KEY].node)) @@ -101,14 +101,14 @@ fun Envelope.parts(): EnvelopeParts { } } -fun EnvelopePart.envelope(format: EnvelopeFormat): Envelope = binary.readWith(format) +public fun EnvelopePart.envelope(format: EnvelopeFormat): Envelope = binary.readWith(format) -val EnvelopePart.name: String? get() = description?.get("name").string +public val EnvelopePart.name: String? get() = description?.get("name").string /** * Represent envelope part by an envelope */ -fun EnvelopePart.envelope(plugin: IOPlugin): Envelope { +public fun EnvelopePart.envelope(plugin: IOPlugin): Envelope { val formatItem = description?.get(PART_FORMAT_KEY) return if (formatItem != null) { val format: EnvelopeFormat = plugin.resolveEnvelopeFormat(formatItem) diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/IOFormat.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/IOFormat.kt index 7946c536..7fe4c970 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/IOFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/IOFormat.kt @@ -20,41 +20,42 @@ import kotlin.reflect.KClass /** * And interface for reading and writing objects into with IO streams */ -interface IOFormat<T : Any> : MetaRepr { - fun Output.writeObject(obj: T) - fun Input.readObject(): T +public interface IOFormat<T : Any> : MetaRepr { + public fun writeObject(output: Output, obj: T) + public fun readObject(input: Input): T - companion object{ - val NAME_KEY = "name".asName() - val META_KEY = "meta".asName() + public companion object { + public val NAME_KEY: Name = "name".asName() + public val META_KEY: Name = "meta".asName() } } -fun <T : Any> Input.readWith(format: IOFormat<T>): T = format.run { readObject() } +public fun <T : Any> Input.readWith(format: IOFormat<T>): T = format.readObject(this@readWith) /** * Read given binary as object using given format */ -fun <T : Any> Binary.readWith(format: IOFormat<T>): T = read { +public fun <T : Any> Binary.readWith(format: IOFormat<T>): T = read { readWith(format) } -fun <T : Any> Output.writeWith(format: IOFormat<T>, obj: T) = format.run { writeObject(obj) } +public fun <T : Any> Output.writeWith(format: IOFormat<T>, obj: T): Unit = + format.run { writeObject(this@writeWith, obj) } -class ListIOFormat<T : Any>(val format: IOFormat<T>) : IOFormat<List<T>> { - override fun Output.writeObject(obj: List<T>) { - writeInt(obj.size) - format.run { +public class ListIOFormat<T : Any>(public val format: IOFormat<T>) : IOFormat<List<T>> { + override fun writeObject(output: Output, obj: List<T>) { + output.writeInt(obj.size) + this.format.run { obj.forEach { - writeObject(it) + writeObject(output, it) } } } - override fun Input.readObject(): List<T> { - val size = readInt() + override fun readObject(input: Input): List<T> { + val size = input.readInt() return format.run { - List(size) { readObject() } + List(size) { readObject(input) } } } @@ -64,9 +65,9 @@ class ListIOFormat<T : Any>(val format: IOFormat<T>) : IOFormat<List<T>> { } } -val <T : Any> IOFormat<T>.list get() = ListIOFormat(this) +//public val <T : Any> IOFormat<T>.list: ListIOFormat<T> get() = ListIOFormat(this) -fun ObjectPool<Buffer>.fill(block: Buffer.() -> Unit): Buffer { +public fun ObjectPool<Buffer>.fill(block: Buffer.() -> Unit): Buffer { val buffer = borrow() return try { buffer.apply(block) @@ -77,50 +78,50 @@ fun ObjectPool<Buffer>.fill(block: Buffer.() -> Unit): Buffer { } @Type(IO_FORMAT_TYPE) -interface IOFormatFactory<T : Any> : Factory<IOFormat<T>>, Named, MetaRepr { +public interface IOFormatFactory<T : Any> : Factory<IOFormat<T>>, Named, MetaRepr { /** * Explicit type for dynamic type checks */ - val type: KClass<out T> + public val type: KClass<out T> override fun toMeta(): Meta = Meta { NAME_KEY put name.toString() } - companion object { - const val IO_FORMAT_TYPE = "io.format" + public companion object { + public const val IO_FORMAT_TYPE: String = "io.format" } } -fun <T : Any> IOFormat<T>.toBinary(obj: T): Binary = Binary { writeObject(obj) } +public fun <T : Any> IOFormat<T>.toBinary(obj: T): Binary = Binary { writeObject(this, obj) } -object DoubleIOFormat : IOFormat<Double>, IOFormatFactory<Double> { +public object DoubleIOFormat : IOFormat<Double>, IOFormatFactory<Double> { override fun invoke(meta: Meta, context: Context): IOFormat<Double> = this override val name: Name = "double".asName() override val type: KClass<out Double> get() = Double::class - override fun Output.writeObject(obj: Double) { - writeDouble(obj) + override fun writeObject(output: Output, obj: kotlin.Double) { + output.writeDouble(obj) } - override fun Input.readObject(): Double = readDouble() + override fun readObject(input: Input): Double = input.readDouble() } -object ValueIOFormat : IOFormat<Value>, IOFormatFactory<Value> { +public object ValueIOFormat : IOFormat<Value>, IOFormatFactory<Value> { override fun invoke(meta: Meta, context: Context): IOFormat<Value> = this override val name: Name = "value".asName() override val type: KClass<out Value> get() = Value::class - override fun Output.writeObject(obj: Value) { - BinaryMetaFormat.run { writeValue(obj) } + override fun writeObject(output: Output, obj: Value) { + BinaryMetaFormat.run { output.writeValue(obj) } } - override fun Input.readObject(): Value { - return (BinaryMetaFormat.run { readMetaItem() } as? MetaItem.ValueItem)?.value + override fun readObject(input: Input): Value { + return (BinaryMetaFormat.run { input.readMetaItem() } as? MetaItem.ValueItem)?.value ?: error("The item is not a value") } } \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/IOPlugin.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/IOPlugin.kt index 73fd26f1..f0c47609 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/IOPlugin.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/IOPlugin.kt @@ -11,14 +11,14 @@ import hep.dataforge.names.Name import hep.dataforge.names.toName import kotlin.reflect.KClass -class IOPlugin(meta: Meta) : AbstractPlugin(meta) { +public class IOPlugin(meta: Meta) : AbstractPlugin(meta) { override val tag: PluginTag get() = Companion.tag - val ioFormatFactories by lazy { - context.content<IOFormatFactory<*>>(IO_FORMAT_TYPE).values + public val ioFormatFactories: Collection<IOFormatFactory<*>> by lazy { + context.gather<IOFormatFactory<*>>(IO_FORMAT_TYPE).values } - fun <T : Any> resolveIOFormat(item: MetaItem<*>, type: KClass<out T>): IOFormat<T>? { + public fun <T : Any> resolveIOFormat(item: MetaItem<*>, type: KClass<out T>): IOFormat<T>? { val key = item.string ?: item.node[NAME_KEY]?.string ?: error("Format name not defined") val name = key.toName() return ioFormatFactories.find { it.name == name }?.let { @@ -29,40 +29,40 @@ class IOPlugin(meta: Meta) : AbstractPlugin(meta) { } - val metaFormatFactories by lazy { - context.content<MetaFormatFactory>(META_FORMAT_TYPE).values + public val metaFormatFactories: Collection<MetaFormatFactory> by lazy { + context.gather<MetaFormatFactory>(META_FORMAT_TYPE).values } - fun resolveMetaFormat(key: Short, meta: Meta = Meta.EMPTY): MetaFormat? = + public fun resolveMetaFormat(key: Short, meta: Meta = Meta.EMPTY): MetaFormat? = metaFormatFactories.find { it.key == key }?.invoke(meta) - fun resolveMetaFormat(name: String, meta: Meta = Meta.EMPTY): MetaFormat? = + public fun resolveMetaFormat(name: String, meta: Meta = Meta.EMPTY): MetaFormat? = metaFormatFactories.find { it.shortName == name }?.invoke(meta) - val envelopeFormatFactories by lazy { - context.content<EnvelopeFormatFactory>(ENVELOPE_FORMAT_TYPE).values + public val envelopeFormatFactories: Collection<EnvelopeFormatFactory> by lazy { + context.gather<EnvelopeFormatFactory>(ENVELOPE_FORMAT_TYPE).values } - fun resolveEnvelopeFormat(name: Name, meta: Meta = Meta.EMPTY): EnvelopeFormat? = + private fun resolveEnvelopeFormat(name: Name, meta: Meta = Meta.EMPTY): EnvelopeFormat? = envelopeFormatFactories.find { it.name == name }?.invoke(meta, context) - fun resolveEnvelopeFormat(item: MetaItem<*>): EnvelopeFormat? { + public fun resolveEnvelopeFormat(item: MetaItem<*>): EnvelopeFormat? { val name = item.string ?: item.node[NAME_KEY]?.string ?: error("Envelope format name not defined") val meta = item.node[META_KEY].node ?: Meta.EMPTY return resolveEnvelopeFormat(name.toName(), meta) } - override fun provideTop(target: String): Map<Name, Any> { + override fun content(target: String): Map<Name, Any> { return when (target) { META_FORMAT_TYPE -> defaultMetaFormats.toMap() ENVELOPE_FORMAT_TYPE -> defaultEnvelopeFormats.toMap() - else -> super.provideTop(target) + else -> super.content(target) } } - companion object : PluginFactory<IOPlugin> { - val defaultMetaFormats: List<MetaFormatFactory> = listOf(JsonMetaFormat, BinaryMetaFormat) - val defaultEnvelopeFormats = listOf(TaggedEnvelopeFormat, TaglessEnvelopeFormat) + public companion object : PluginFactory<IOPlugin> { + public val defaultMetaFormats: List<MetaFormatFactory> = listOf(JsonMetaFormat, BinaryMetaFormat) + public val defaultEnvelopeFormats: List<EnvelopeFormatFactory> = listOf(TaggedEnvelopeFormat, TaglessEnvelopeFormat) override val tag: PluginTag = PluginTag("io", group = PluginTag.DATAFORGE_GROUP) @@ -71,4 +71,4 @@ class IOPlugin(meta: Meta) : AbstractPlugin(meta) { } } -val Context.io: IOPlugin get() = plugins.fetch(IOPlugin) \ No newline at end of file +public val Context.io: IOPlugin get() = plugins.fetch(IOPlugin) \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/JsonMetaFormat.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/JsonMetaFormat.kt index e19a9f7d..2be2fe51 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/JsonMetaFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/JsonMetaFormat.kt @@ -12,45 +12,46 @@ import hep.dataforge.meta.toJson import hep.dataforge.meta.toMetaItem import kotlinx.io.Input import kotlinx.io.Output -import kotlinx.io.readByteArray +import kotlinx.io.text.readUtf8String import kotlinx.io.text.writeUtf8String -import kotlinx.serialization.UnstableDefault import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonObjectSerializer +import kotlinx.serialization.json.JsonObject -@OptIn(UnstableDefault::class) -class JsonMetaFormat(private val json: Json = DEFAULT_JSON) : MetaFormat { +/** + * A Json format for Meta representation + */ +public class JsonMetaFormat(private val json: Json = DEFAULT_JSON) : MetaFormat { - override fun Output.writeMeta(meta: Meta, descriptor: NodeDescriptor?) { + override fun writeMeta(output: Output, meta: Meta, descriptor: NodeDescriptor?) { val jsonObject = meta.toJson(descriptor) - writeUtf8String(json.stringify(JsonObjectSerializer, jsonObject)) + output.writeUtf8String(json.encodeToString(JsonObject.serializer(), jsonObject)) } - override fun toMeta(): Meta = Meta{ + override fun toMeta(): Meta = Meta { NAME_KEY put name.toString() } - override fun Input.readMeta(descriptor: NodeDescriptor?): Meta { - val str = readByteArray().decodeToString() - val jsonElement = json.parseJson(str) + override fun readMeta(input: Input, descriptor: NodeDescriptor?): Meta { + val str = input.readUtf8String()//readByteArray().decodeToString() + val jsonElement = json.parseToJsonElement(str) val item = jsonElement.toMetaItem(descriptor) return item.node ?: Meta.EMPTY } - companion object : MetaFormatFactory { - val DEFAULT_JSON = Json { prettyPrint = true } + public companion object : MetaFormatFactory { + public val DEFAULT_JSON: Json = Json { prettyPrint = true } override fun invoke(meta: Meta, context: Context): MetaFormat = default - override val shortName = "json" + override val shortName: String = "json" override val key: Short = 0x4a53//"JS" private val default = JsonMetaFormat() - override fun Output.writeMeta(meta: Meta, descriptor: NodeDescriptor?) = - default.run { writeMeta(meta, descriptor) } + override fun writeMeta(output: Output, meta: Meta, descriptor: NodeDescriptor?): Unit = + default.run { writeMeta(output, meta, descriptor) } - override fun Input.readMeta(descriptor: NodeDescriptor?): Meta = - default.run { readMeta(descriptor) } + override fun readMeta(input: Input, descriptor: NodeDescriptor?): Meta = + default.run { readMeta(input, descriptor) } } } diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/MetaFormat.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/MetaFormat.kt index 4b893a4a..f3e26d2a 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/MetaFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/MetaFormat.kt @@ -17,46 +17,50 @@ import kotlin.reflect.KClass /** * A format for meta serialization */ +public interface MetaFormat : IOFormat<Meta> { -interface MetaFormat : IOFormat<Meta> { - - override fun Output.writeObject(obj: Meta) { - writeMeta(obj, null) + override fun writeObject(output: Output, obj: Meta) { + writeMeta(output, obj, null) } - override fun Input.readObject(): Meta = readMeta() + override fun readObject(input: Input): Meta = readMeta(input) - fun Output.writeMeta(meta: Meta, descriptor: NodeDescriptor? = null) - fun Input.readMeta(descriptor: NodeDescriptor? = null): Meta + public fun writeMeta( + output: Output, + meta: Meta, + descriptor: NodeDescriptor? = null, + ) + + public fun readMeta(input: Input, descriptor: NodeDescriptor? = null): Meta } @Type(META_FORMAT_TYPE) -interface MetaFormatFactory : IOFormatFactory<Meta>, MetaFormat { - val shortName: String +public interface MetaFormatFactory : IOFormatFactory<Meta>, MetaFormat { + public val shortName: String override val name: Name get() = "meta".asName() + shortName override val type: KClass<out Meta> get() = Meta::class - val key: Short get() = name.hashCode().toShort() + public val key: Short get() = name.hashCode().toShort() override operator fun invoke(meta: Meta, context: Context): MetaFormat - companion object { - const val META_FORMAT_TYPE = "io.format.meta" + public companion object { + public const val META_FORMAT_TYPE: String = "io.format.meta" } } -fun Meta.toString(format: MetaFormat): String = buildByteArray { - format.run { writeObject(this@toString) } +public fun Meta.toString(format: MetaFormat): String = buildByteArray { + format.run { writeObject(this@buildByteArray, this@toString) } }.decodeToString() -fun Meta.toString(formatFactory: MetaFormatFactory): String = toString(formatFactory()) +public fun Meta.toString(formatFactory: MetaFormatFactory): String = toString(formatFactory()) -fun MetaFormat.parse(str: String): Meta { - return ByteArrayInput(str.encodeToByteArray()).use { it.readObject() } +public fun MetaFormat.parse(str: String): Meta { + return ByteArrayInput(str.encodeToByteArray()).use { readObject(it) } } -fun MetaFormatFactory.parse(str: String, formatMeta: Meta): Meta = invoke(formatMeta).parse(str) +public fun MetaFormatFactory.parse(str: String, formatMeta: Meta): Meta = invoke(formatMeta).parse(str) diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Responder.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Responder.kt index e3545782..2710ffa9 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Responder.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/Responder.kt @@ -1,8 +1,12 @@ package hep.dataforge.io -interface Responder { +/** + * An object that could respond to external messages asynchronously + */ +public interface Responder { /** * Send a request and wait for response for this specific request */ - suspend fun respond(request: Envelope): Envelope -} \ No newline at end of file + public suspend fun respond(request: Envelope): Envelope +} + diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaggedEnvelopeFormat.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaggedEnvelopeFormat.kt index ebcca243..389c5054 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaggedEnvelopeFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaggedEnvelopeFormat.kt @@ -12,9 +12,13 @@ import hep.dataforge.names.plus import hep.dataforge.names.toName import kotlinx.io.* -class TaggedEnvelopeFormat( - val io: IOPlugin, - val version: VERSION = VERSION.DF02 +/** + * A streaming-friendly envelope format with a short binary tag. + * TODO add description + */ +public class TaggedEnvelopeFormat( + public val io: IOPlugin, + public val version: VERSION = VERSION.DF02, ) : EnvelopeFormat { // private val metaFormat = io.metaFormat(metaFormatKey) @@ -37,18 +41,23 @@ class TaggedEnvelopeFormat( writeRawString(END_SEQUENCE) } - override fun Output.writeEnvelope(envelope: Envelope, metaFormatFactory: MetaFormatFactory, formatMeta: Meta) { - val metaFormat = metaFormatFactory.invoke(formatMeta, io.context) + override fun writeEnvelope( + output: Output, + envelope: Envelope, + metaFormatFactory: MetaFormatFactory, + formatMeta: Meta, + ) { + val metaFormat = metaFormatFactory.invoke(formatMeta, this@TaggedEnvelopeFormat.io.context) val metaBytes = metaFormat.toBinary(envelope.meta) val actualSize: ULong = (envelope.data?.size ?: 0).toULong() val tag = Tag(metaFormatFactory.key, metaBytes.size.toUInt() + 2u, actualSize) - writeBinary(tag.toBinary()) - writeBinary(metaBytes) - writeRawString("\r\n") + output.writeBinary(tag.toBinary()) + output.writeBinary(metaBytes) + output.writeRawString("\r\n") envelope.data?.let { - writeBinary(it) + output.writeBinary(it) } - flush() + output.flush() } /** @@ -57,34 +66,27 @@ class TaggedEnvelopeFormat( * @param input an input to read from * @param formats a collection of meta formats to resolve */ - override fun Input.readObject(): Envelope { - val tag = readTag(version) + override fun readObject(input: Input): Envelope { + val tag = input.readTag(this.version) val metaFormat = io.resolveMetaFormat(tag.metaFormatKey) ?: error("Meta format with key ${tag.metaFormatKey} not found") - val meta: Meta = limit(tag.metaSize.toInt()).run { - metaFormat.run { - readObject() - } - } + val meta: Meta = metaFormat.readObject(input.limit(tag.metaSize.toInt())) - val data = readBinary(tag.dataSize.toInt()) + val data = input.readBinary(tag.dataSize.toInt()) return SimpleEnvelope(meta, data) } - override fun Input.readPartial(): PartialEnvelope { - val tag = readTag(version) + override fun readPartial(input: Input): PartialEnvelope { + val tag = input.readTag(this.version) val metaFormat = io.resolveMetaFormat(tag.metaFormatKey) ?: error("Meta format with key ${tag.metaFormatKey} not found") - val meta: Meta = limit(tag.metaSize.toInt()).run { - metaFormat.run { - readObject() - } - } + val meta: Meta = metaFormat.readObject(input.limit(tag.metaSize.toInt())) + return PartialEnvelope(meta, version.tagSize + tag.metaSize, tag.dataSize) } @@ -92,10 +94,10 @@ class TaggedEnvelopeFormat( private data class Tag( val metaFormatKey: Short, val metaSize: UInt, - val dataSize: ULong + val dataSize: ULong, ) - enum class VERSION(val tagSize: UInt) { + public enum class VERSION(public val tagSize: UInt) { DF02(20u), DF03(24u) } @@ -107,7 +109,7 @@ class TaggedEnvelopeFormat( } } - companion object : EnvelopeFormatFactory { + public companion object : EnvelopeFormatFactory { private const val START_SEQUENCE = "#~" private const val END_SEQUENCE = "~#\r\n" @@ -158,16 +160,24 @@ class TaggedEnvelopeFormat( private val default by lazy { invoke() } - override fun Input.readPartial(): PartialEnvelope = - default.run { readPartial() } - - override fun Output.writeEnvelope(envelope: Envelope, metaFormatFactory: MetaFormatFactory, formatMeta: Meta) = - default.run { writeEnvelope(envelope, metaFormatFactory, formatMeta) } - - override fun Input.readObject(): Envelope = - default.run { readObject() } + override fun readPartial(input: Input): PartialEnvelope = + default.run { readPartial(input) } + override fun writeEnvelope( + output: Output, + envelope: Envelope, + metaFormatFactory: MetaFormatFactory, + formatMeta: Meta, + ): Unit = default.run { + writeEnvelope( + output, + envelope, + metaFormatFactory, + formatMeta + ) + } + override fun readObject(input: Input): Envelope = default.readObject(input) } } \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaglessEnvelopeFormat.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaglessEnvelopeFormat.kt index c800d878..f89f9bbb 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaglessEnvelopeFormat.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/TaglessEnvelopeFormat.kt @@ -7,15 +7,20 @@ import hep.dataforge.meta.Meta import hep.dataforge.meta.get import hep.dataforge.meta.isEmpty import hep.dataforge.meta.string +import hep.dataforge.names.Name import hep.dataforge.names.asName import kotlinx.io.* import kotlinx.io.text.readUtf8Line import kotlinx.io.text.writeUtf8String import kotlin.collections.set -class TaglessEnvelopeFormat( - val io: IOPlugin, - val meta: Meta = Meta.EMPTY +/** + * A text envelope format with human-readable tag. + * TODO add description + */ +public class TaglessEnvelopeFormat( + public val io: IOPlugin, + public val meta: Meta = Meta.EMPTY, ) : EnvelopeFormat { private val metaStart = meta[META_START_PROPERTY].string ?: DEFAULT_META_START @@ -25,39 +30,46 @@ class TaglessEnvelopeFormat( writeUtf8String("#? $key: $value;\r\n") } - override fun Output.writeEnvelope(envelope: Envelope, metaFormatFactory: MetaFormatFactory, formatMeta: Meta) { - val metaFormat = metaFormatFactory(formatMeta, io.context) + override fun writeEnvelope( + output: Output, + envelope: Envelope, + metaFormatFactory: MetaFormatFactory, + formatMeta: Meta + ) { + val metaFormat = metaFormatFactory(formatMeta, this.io.context) //printing header - writeRawString(TAGLESS_ENVELOPE_HEADER + "\r\n") + output.writeRawString(TAGLESS_ENVELOPE_HEADER + "\r\n") //printing all properties - writeProperty(META_TYPE_PROPERTY, metaFormatFactory.shortName) + output.writeProperty(META_TYPE_PROPERTY, + metaFormatFactory.shortName) //TODO add optional metaFormat properties val actualSize: Int = envelope.data?.size ?: 0 - writeProperty(DATA_LENGTH_PROPERTY, actualSize) + output.writeProperty(DATA_LENGTH_PROPERTY, actualSize) //Printing meta if (!envelope.meta.isEmpty()) { val metaBytes = metaFormat.toBinary(envelope.meta) - writeProperty(META_LENGTH_PROPERTY, metaBytes.size + 2) - writeUtf8String(metaStart + "\r\n") - writeBinary(metaBytes) - writeRawString("\r\n") + output.writeProperty(META_LENGTH_PROPERTY, + metaBytes.size + 2) + output.writeUtf8String(this.metaStart + "\r\n") + output.writeBinary(metaBytes) + output.writeRawString("\r\n") } //Printing data envelope.data?.let { data -> - writeUtf8String(dataStart + "\r\n") - writeBinary(data) + output.writeUtf8String(this.dataStart + "\r\n") + output.writeBinary(data) } } - override fun Input.readObject(): Envelope { + override fun readObject(input: Input): Envelope { var line: String do { - line = readUtf8Line() // ?: error("Input does not contain tagless envelope header") + line = input.readUtf8Line() // ?: error("Input does not contain tagless envelope header") } while (!line.startsWith(TAGLESS_ENVELOPE_HEADER)) val properties = HashMap<String, String>() @@ -70,8 +82,8 @@ class TaglessEnvelopeFormat( properties[key] = value } //If can't read line, return envelope without data - if (exhausted()) return SimpleEnvelope(Meta.EMPTY, null) - line = readUtf8Line() + if (input.exhausted()) return SimpleEnvelope(Meta.EMPTY, null) + line = input.readUtf8Line() } var meta: Meta = Meta.EMPTY @@ -80,19 +92,15 @@ class TaglessEnvelopeFormat( val metaFormat = properties[META_TYPE_PROPERTY]?.let { io.resolveMetaFormat(it) } ?: JsonMetaFormat val metaSize = properties[META_LENGTH_PROPERTY]?.toInt() meta = if (metaSize != null) { - limit(metaSize).run { - metaFormat.run { readObject() } - } + metaFormat.readObject(input.limit(metaSize)) } else { - metaFormat.run { - readObject() - } + metaFormat.readObject(input) } } do { try { - line = readUtf8Line() + line = input.readUtf8Line() } catch (ex: EOFException) { //returning an Envelope without data if end of input is reached return SimpleEnvelope(meta, null) @@ -100,24 +108,24 @@ class TaglessEnvelopeFormat( } while (!line.startsWith(dataStart)) val data: Binary? = if (properties.containsKey(DATA_LENGTH_PROPERTY)) { - readBinary(properties[DATA_LENGTH_PROPERTY]!!.toInt()) + input.readBinary(properties[DATA_LENGTH_PROPERTY]!!.toInt()) // val bytes = ByteArray(properties[DATA_LENGTH_PROPERTY]!!.toInt()) // readByteArray(bytes) // bytes.asBinary() } else { Binary { - copyTo(this) + input.copyTo(this) } } return SimpleEnvelope(meta, data) } - override fun Input.readPartial(): PartialEnvelope { + override fun readPartial(input: Input): PartialEnvelope { var offset = 0u var line: String do { - line = readUtf8Line()// ?: error("Input does not contain tagless envelope header") + line = input.readUtf8Line()// ?: error("Input does not contain tagless envelope header") offset += line.encodeToByteArray().size.toUInt() } while (!line.startsWith(TAGLESS_ENVELOPE_HEADER)) val properties = HashMap<String, String>() @@ -131,7 +139,7 @@ class TaglessEnvelopeFormat( properties[key] = value } try { - line = readUtf8Line() + line = input.readUtf8Line() offset += line.encodeToByteArray().size.toUInt() } catch (ex: EOFException) { return PartialEnvelope(Meta.EMPTY, offset.toUInt(), 0.toULong()) @@ -145,16 +153,14 @@ class TaglessEnvelopeFormat( val metaSize = properties[META_LENGTH_PROPERTY]?.toInt() meta = if (metaSize != null) { offset += metaSize.toUInt() - limit(metaSize).run { - metaFormat.run { readObject() } - } + metaFormat.readObject(input.limit(metaSize)) } else { error("Can't partially read an envelope with undefined meta size") } } do { - line = readUtf8Line() //?: return PartialEnvelope(Meta.EMPTY, offset.toUInt(), 0.toULong()) + line = input.readUtf8Line() //?: return PartialEnvelope(Meta.EMPTY, offset.toUInt(), 0.toULong()) offset += line.encodeToByteArray().size.toUInt() //returning an Envelope without data if end of input is reached } while (!line.startsWith(dataStart)) @@ -168,26 +174,26 @@ class TaglessEnvelopeFormat( META_KEY put meta } - companion object : EnvelopeFormatFactory { + public companion object : EnvelopeFormatFactory { - private val propertyPattern = "#\\?\\s*(?<key>[\\w.]*)\\s*:\\s*(?<value>[^;]*);?".toRegex() + private val propertyPattern = "#\\?\\s*([\\w.]*)\\s*:\\s*([^;]*);?".toRegex() - const val META_TYPE_PROPERTY = "metaType" - const val META_LENGTH_PROPERTY = "metaLength" - const val DATA_LENGTH_PROPERTY = "dataLength" + public const val META_TYPE_PROPERTY: String = "metaType" + public const val META_LENGTH_PROPERTY: String = "metaLength" + public const val DATA_LENGTH_PROPERTY: String = "dataLength" - const val TAGLESS_ENVELOPE_TYPE = "tagless" + public const val TAGLESS_ENVELOPE_TYPE: String = "tagless" - const val TAGLESS_ENVELOPE_HEADER = "#~DFTL~#" - const val META_START_PROPERTY = "metaSeparator" - const val DEFAULT_META_START = "#~META~#" - const val DATA_START_PROPERTY = "dataSeparator" - const val DEFAULT_DATA_START = "#~DATA~#" + public const val TAGLESS_ENVELOPE_HEADER: String = "#~DFTL~#" + public const val META_START_PROPERTY: String = "metaSeparator" + public const val DEFAULT_META_START: String = "#~META~#" + public const val DATA_START_PROPERTY: String = "dataSeparator" + public const val DEFAULT_DATA_START: String = "#~DATA~#" - const val code: Int = 0x4446544c //DFTL + public const val code: Int = 0x4446544c //DFTL - override val name = TAGLESS_ENVELOPE_TYPE.asName() + override val name: Name = TAGLESS_ENVELOPE_TYPE.asName() override fun invoke(meta: Meta, context: Context): EnvelopeFormat { return TaglessEnvelopeFormat(context.io, meta) @@ -195,14 +201,24 @@ class TaglessEnvelopeFormat( private val default by lazy { invoke() } - override fun Input.readPartial(): PartialEnvelope = - default.run { readPartial() } + override fun readPartial(input: Input): PartialEnvelope = + default.run { readPartial(input) } - override fun Output.writeEnvelope(envelope: Envelope, metaFormatFactory: MetaFormatFactory, formatMeta: Meta) = - default.run { writeEnvelope(envelope, metaFormatFactory, formatMeta) } + override fun writeEnvelope( + output: Output, + envelope: Envelope, + metaFormatFactory: MetaFormatFactory, + formatMeta: Meta, + ): Unit = default.run { + writeEnvelope( + output, + envelope, + metaFormatFactory, + formatMeta + ) + } - override fun Input.readObject(): Envelope = - default.run { readObject() } + override fun readObject(input: Input): Envelope = default.readObject(input) override fun peekFormat(io: IOPlugin, input: Input): EnvelopeFormat? { return try { diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/functions/FunctionServer.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/functions/FunctionServer.kt deleted file mode 100644 index 2eca605c..00000000 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/functions/FunctionServer.kt +++ /dev/null @@ -1,75 +0,0 @@ -package hep.dataforge.io.functions - -import hep.dataforge.context.ContextAware -import hep.dataforge.io.IOFormat -import hep.dataforge.io.IOPlugin -import hep.dataforge.meta.Meta -import hep.dataforge.meta.get -import hep.dataforge.names.asName -import hep.dataforge.names.plus -import kotlin.reflect.KClass - - -/** - * A server that could produce asynchronous function values - */ -interface FunctionServer : ContextAware { - /** - * Call a function with given name and descriptor - */ - suspend fun <T : Any, R : Any> call(meta: Meta, arg: T, inputType: KClass<out T>, outputType: KClass<out R>): R - - suspend fun <T : Any, R : Any> callMany( - meta: Meta, - arg: List<T>, - inputType: KClass<out T>, - outputType: KClass<out R> - ): List<R> = List(arg.size) { - call<T, R>(meta, arg[it], inputType, outputType) - } - - /** - * Get a generic suspended function with given name and descriptor - */ - fun <T : Any, R : Any> function( - meta: Meta, - inputType: KClass<out T>, - outputType: KClass<out R> - ): (suspend (T) -> R) = { call(meta, it, inputType, outputType) } - - companion object { - const val FUNCTION_NAME_KEY = "function" - val FORMAT_KEY = "format".asName() - val INPUT_FORMAT_KEY = FORMAT_KEY + "input" - val OUTPUT_FORMAT_KEY = FORMAT_KEY + "output" - } -} - -suspend inline fun <reified T : Any, reified R : Any> FunctionServer.call(meta: Meta, arg: T) = - call(meta, arg, T::class, R::class) - -suspend inline fun <reified T : Any, reified R : Any> FunctionServer.callMany(meta: Meta, arg: List<T>) = - callMany(meta, arg, T::class, R::class) - -inline fun <reified T : Any, reified R : Any> FunctionServer.function(meta: Meta) = - function(meta, T::class, R::class) - -fun <T : Any> IOPlugin.getInputFormat(meta: Meta, type: KClass<out T>): IOFormat<T> { - return meta[FunctionServer.INPUT_FORMAT_KEY]?.let { - resolveIOFormat<T>(it, type) - } ?: error("Input format not resolved") -} - -fun <R : Any> IOPlugin.getOutputFormat(meta: Meta, type: KClass<out R>): IOFormat<R> { - return meta[FunctionServer.OUTPUT_FORMAT_KEY]?.let { - resolveIOFormat<R>(it, type) - } ?: error("Input format not resolved") -} - -inline fun <reified T : Any> IOPlugin.getInputFormat(meta: Meta): IOFormat<T> = - getInputFormat(meta, T::class) - -inline fun <reified R : Any> IOPlugin.getOutputFormat(meta: Meta): IOFormat<R> = - getOutputFormat(meta, R::class) - - diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/functions/RemoteFunctionClient.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/functions/RemoteFunctionClient.kt deleted file mode 100644 index 7c294891..00000000 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/functions/RemoteFunctionClient.kt +++ /dev/null @@ -1,98 +0,0 @@ -package hep.dataforge.io.functions - -import hep.dataforge.context.Context -import hep.dataforge.context.ContextAware -import hep.dataforge.io.* -import hep.dataforge.meta.Meta -import hep.dataforge.meta.get -import hep.dataforge.meta.int -import kotlin.reflect.KClass - -class RemoteFunctionClient(override val context: Context, val responder: Responder) : FunctionServer, ContextAware { - - private fun <T : Any> IOPlugin.encodeOne( - meta: Meta, - value: T, - valueType: KClass<out T> = value::class - ): Envelope = Envelope.invoke { - meta(meta) - type = REQUEST_TYPE - data { - val inputFormat: IOFormat<T> = getInputFormat(meta, valueType) - inputFormat.run { - writeObject(value) - } - } - } - - private fun <T : Any> IOPlugin.encodeMany( - meta: Meta, - values: List<T>, - valueType: KClass<out T> - ): Envelope = Envelope.invoke { - meta(meta) - type = REQUEST_TYPE - meta { - SIZE_KEY put values.size - } - data { - val inputFormat: IOFormat<T> = getInputFormat(meta, valueType) - inputFormat.run { - values.forEach { - writeObject(it) - } - } - } - } - - private fun <R : Any> IOPlugin.decode(envelope: Envelope, valueType: KClass<out R>): List<R> { - require(envelope.type == RESPONSE_TYPE) { "Unexpected message type: ${envelope.type}" } - val size = envelope.meta[SIZE_KEY].int ?: 1 - - return if (size == 0) { - emptyList() - } else { - val outputFormat: IOFormat<R> = getOutputFormat(envelope.meta, valueType) - envelope.data?.read { - List<R>(size) { - outputFormat.run { - readObject() - } - } - } ?: error("Message does not contain data") - } - } - - private val plugin by lazy { - context.plugins.load(IOPlugin) - } - - override suspend fun <T : Any, R : Any> call( - meta: Meta, - arg: T, - inputType: KClass<out T>, - outputType: KClass<out R> - ): R = plugin.run { - val request = encodeOne(meta, arg) - val response = responder.respond(request) - return decode<R>(response, outputType).first() - } - - override suspend fun <T : Any, R : Any> callMany( - meta: Meta, - arg: List<T>, - inputType: KClass<out T>, - outputType: KClass<out R> - ): List<R> = plugin.run { - val request = encodeMany(meta, arg, inputType) - val response = responder.respond(request) - return decode<R>(response, outputType) - } - - companion object { - const val REQUEST_TYPE = "function.request" - const val RESPONSE_TYPE = "function.response" - - const val SIZE_KEY = "size" - } -} \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/functions/RemoteFunctionServer.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/functions/RemoteFunctionServer.kt deleted file mode 100644 index 8252b1d3..00000000 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/functions/RemoteFunctionServer.kt +++ /dev/null @@ -1,58 +0,0 @@ -package hep.dataforge.io.functions - -import hep.dataforge.context.Context -import hep.dataforge.context.ContextAware -import hep.dataforge.io.Envelope -import hep.dataforge.io.IOPlugin -import hep.dataforge.io.Responder -import hep.dataforge.io.type -import hep.dataforge.meta.get -import hep.dataforge.meta.int - -class RemoteFunctionServer( - override val context: Context, - val functionServer: FunctionServer -) : ContextAware, Responder { - - private val plugin by lazy { - context.plugins.load(IOPlugin) - } - - - override suspend fun respond(request: Envelope): Envelope { - require(request.type == RemoteFunctionClient.REQUEST_TYPE) { "Unexpected message type: ${request.type}" } - - val inputFormat = plugin.getInputFormat<Any>(request.meta) - val outputFormat = plugin.getOutputFormat<Any>(request.meta) - - val size = request.meta[RemoteFunctionClient.SIZE_KEY].int ?: 1 - - val input = request.data?.read { - inputFormat.run { - List(size) { - readObject() - } - } - } ?: error("Input is empty") - - val output = functionServer.callMany<Any, Any>( - request.meta, - input - ) - - return Envelope.invoke { - meta { - meta(request.meta) - } - type = RemoteFunctionClient.RESPONSE_TYPE - data { - outputFormat.run { - output.forEach { - writeObject(it) - } - } - } - - } - } -} \ No newline at end of file diff --git a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/ioMisc.kt b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/ioMisc.kt index 9b214c5c..283f7638 100644 --- a/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/ioMisc.kt +++ b/dataforge-io/src/commonMain/kotlin/hep/dataforge/io/ioMisc.kt @@ -3,26 +3,26 @@ package hep.dataforge.io import kotlinx.io.* import kotlin.math.min -fun Output.writeRawString(str: String) { +public fun Output.writeRawString(str: String) { str.forEach { writeByte(it.toByte()) } } -fun Input.readRawString(size: Int): String { +public fun Input.readRawString(size: Int): String { val array = CharArray(size) { readByte().toChar() } - return String(array) + return array.concatToString() } -inline fun buildByteArray(expectedSize: Int = 16, block: Output.() -> Unit): ByteArray = +public inline fun buildByteArray(expectedSize: Int = 16, block: Output.() -> Unit): ByteArray = ByteArrayOutput(expectedSize).apply(block).toByteArray() @Suppress("FunctionName") -inline fun Binary(expectedSize: Int = 16, block: Output.() -> Unit): Binary = +public inline fun Binary(expectedSize: Int = 16, block: Output.() -> Unit): Binary = buildByteArray(expectedSize, block).asBinary() /** * View section of a [Binary] as an independent binary */ -class BinaryView(private val source: Binary, private val start: Int, override val size: Int) : Binary { +public class BinaryView(private val source: Binary, private val start: Int, override val size: Int) : Binary { init { require(start > 0) @@ -34,6 +34,6 @@ class BinaryView(private val source: Binary, private val start: Int, override va } } -fun Binary.view(start: Int, size: Int) = BinaryView(this, start, size) +public fun Binary.view(start: Int, size: Int): BinaryView = BinaryView(this, start, size) -operator fun Binary.get(range: IntRange) = view(range.first, range.last - range.first) \ No newline at end of file +public operator fun Binary.get(range: IntRange): BinaryView = view(range.first, range.last - range.first) \ No newline at end of file diff --git a/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/EnvelopeFormatTest.kt b/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/EnvelopeFormatTest.kt index 0fd09abf..8bcc54cd 100644 --- a/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/EnvelopeFormatTest.kt +++ b/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/EnvelopeFormatTest.kt @@ -23,9 +23,9 @@ class EnvelopeFormatTest { @Test fun testTaggedFormat(){ TaggedEnvelopeFormat.run { - val byteArray = this.toByteArray(envelope) + val byteArray = writeToByteArray(envelope) //println(byteArray.decodeToString()) - val res = readByteArray(byteArray) + val res = readFromByteArray(byteArray) assertEquals(envelope.meta,res.meta) val double = res.data?.read { readDouble() @@ -37,9 +37,9 @@ class EnvelopeFormatTest { @Test fun testTaglessFormat(){ TaglessEnvelopeFormat.run { - val byteArray = toByteArray(envelope) + val byteArray = writeToByteArray(envelope) //println(byteArray.decodeToString()) - val res = readByteArray(byteArray) + val res = readFromByteArray(byteArray) assertEquals(envelope.meta,res.meta) val double = res.data?.read { readDouble() diff --git a/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/MetaFormatTest.kt b/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/MetaFormatTest.kt index a470cf0a..cb8ba54b 100644 --- a/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/MetaFormatTest.kt +++ b/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/MetaFormatTest.kt @@ -3,18 +3,16 @@ package hep.dataforge.io import hep.dataforge.meta.* import hep.dataforge.meta.JsonMeta.Companion.JSON_ARRAY_KEY import kotlinx.io.asBinary -import kotlinx.serialization.json.JsonPrimitive -import kotlinx.serialization.json.json -import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.* import kotlin.test.Test import kotlin.test.assertEquals fun Meta.toByteArray(format: MetaFormat = JsonMetaFormat) = buildByteArray { - format.run { writeObject(this@toByteArray) } + format.writeObject(this@buildByteArray, this@toByteArray) } fun MetaFormat.fromByteArray(packet: ByteArray): Meta { - return packet.asBinary().read { readObject() } + return packet.asBinary().read { readObject(this) } } class MetaFormatTest { @@ -57,21 +55,21 @@ class MetaFormatTest { @Test fun testJsonToMeta() { - val json = jsonArray { + val json = buildJsonArray { //top level array - +jsonArray { - +JsonPrimitive(88) - +json { - "c" to "aasdad" - "d" to true - } - } - +"value" - +jsonArray { - +JsonPrimitive(1.0) - +JsonPrimitive(2.0) - +JsonPrimitive(3.0) - } + add(buildJsonArray { + add(JsonPrimitive(88)) + add(buildJsonObject { + put("c", "aasdad") + put("d", true) + }) + }) + add("value") + add(buildJsonArray { + add(JsonPrimitive(1.0)) + add(JsonPrimitive(2.0)) + add(JsonPrimitive(3.0)) + }) } val meta = json.toMetaItem().node!! diff --git a/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/MetaSerializerTest.kt b/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/MetaSerializerTest.kt index dc8e5016..23fef5d5 100644 --- a/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/MetaSerializerTest.kt +++ b/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/MetaSerializerTest.kt @@ -1,12 +1,19 @@ package hep.dataforge.io -import hep.dataforge.meta.* +import hep.dataforge.meta.Meta +import hep.dataforge.meta.MetaItem +import hep.dataforge.meta.MetaSerializer import hep.dataforge.names.Name import hep.dataforge.names.toName +import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.cbor.Cbor +import kotlinx.serialization.json.Json import kotlin.test.Test import kotlin.test.assertEquals +val JSON_PRETTY: Json = Json { prettyPrint = true; useArrayPolymorphism = true } +val JSON_PLAIN: Json = Json { prettyPrint = false; useArrayPolymorphism = true } + class MetaSerializerTest { val meta = Meta { "a" put 22 @@ -19,29 +26,33 @@ class MetaSerializerTest { @Test fun testMetaSerialization() { - val string = JSON_PRETTY.stringify(MetaSerializer, meta) - val restored = JSON_PLAIN.parse(MetaSerializer, string) - assertEquals(restored, meta) + val string = JSON_PRETTY.encodeToString(MetaSerializer, meta) + println(string) + val restored = JSON_PLAIN.decodeFromString(MetaSerializer, string) + assertEquals(meta, restored) } + @OptIn(ExperimentalSerializationApi::class) @Test fun testCborSerialization() { - val bytes = Cbor.dump(MetaSerializer, meta) - println(bytes.contentToString()) - val restored = Cbor.load(MetaSerializer, bytes) - assertEquals(restored, meta) + val bytes = Cbor.encodeToByteArray(MetaSerializer, meta) + println(bytes.decodeToString()) + val restored = Cbor.decodeFromByteArray(MetaSerializer, bytes) + assertEquals(meta, restored) } @Test fun testNameSerialization() { val name = "a.b.c".toName() - val string = JSON_PRETTY.stringify(Name.serializer(), name) - val restored = JSON_PLAIN.parse(Name.serializer(), string) - assertEquals(restored, name) + val string = JSON_PRETTY.encodeToString(Name.serializer(), name) + val restored = JSON_PLAIN.decodeFromString(Name.serializer(), string) + assertEquals(name, restored) } + @OptIn(ExperimentalSerializationApi::class) @Test fun testMetaItemDescriptor() { val descriptor = MetaItem.serializer(MetaSerializer).descriptor.getElementDescriptor(0) + println(descriptor) } } \ No newline at end of file diff --git a/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/ioTestUtils.kt b/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/ioTestUtils.kt index 2694ff8f..55831f03 100644 --- a/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/ioTestUtils.kt +++ b/dataforge-io/src/commonTest/kotlin/hep/dataforge/io/ioTestUtils.kt @@ -3,5 +3,5 @@ package hep.dataforge.io import kotlinx.io.ByteArrayInput import kotlinx.io.use -fun <T : Any> IOFormat<T>.toByteArray(obj: T): ByteArray = buildByteArray { writeObject(obj) } -fun <T : Any> IOFormat<T>.readByteArray(array: ByteArray): T = ByteArrayInput(array).use { it.readObject() } \ No newline at end of file +fun <T : Any> IOFormat<T>.writeToByteArray(obj: T): ByteArray = buildByteArray { writeObject(this, obj) } +fun <T : Any> IOFormat<T>.readFromByteArray(array: ByteArray): T = ByteArrayInput(array).use { readObject(it) } \ No newline at end of file diff --git a/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/fileIO.kt b/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/fileIO.kt index 044cf932..0e53ed89 100644 --- a/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/fileIO.kt +++ b/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/fileIO.kt @@ -11,12 +11,12 @@ import java.nio.file.StandardOpenOption import kotlin.reflect.full.isSuperclassOf import kotlin.streams.asSequence -fun <R> Path.read(block: Input.() -> R): R = asBinary().read(block = block) +public fun <R> Path.read(block: Input.() -> R): R = asBinary().read(block = block) /** * Write a live output to a newly created file. If file does not exist, throws error */ -fun Path.write(block: Output.() -> Unit): Unit { +public fun Path.write(block: Output.() -> Unit): Unit { val stream = Files.newOutputStream(this, StandardOpenOption.WRITE, StandardOpenOption.CREATE_NEW) stream.asOutput().use(block) } @@ -24,7 +24,7 @@ fun Path.write(block: Output.() -> Unit): Unit { /** * Create a new file or append to exiting one with given output [block] */ -fun Path.append(block: Output.() -> Unit): Unit { +public fun Path.append(block: Output.() -> Unit): Unit { val stream = Files.newOutputStream( this, StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE @@ -35,7 +35,7 @@ fun Path.append(block: Output.() -> Unit): Unit { /** * Create a new file or replace existing one using given output [block] */ -fun Path.rewrite(block: Output.() -> Unit): Unit { +public fun Path.rewrite(block: Output.() -> Unit): Unit { val stream = Files.newOutputStream( this, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE @@ -43,9 +43,9 @@ fun Path.rewrite(block: Output.() -> Unit): Unit { stream.asOutput().use(block) } -fun Path.readEnvelope(format: EnvelopeFormat): Envelope { +public fun Path.readEnvelope(format: EnvelopeFormat): Envelope { val partialEnvelope: PartialEnvelope = asBinary().read { - format.run { readPartial() } + format.run { readPartial(this@read) } } val offset: Int = partialEnvelope.dataOffset.toInt() val size: Int = partialEnvelope.dataSize?.toInt() ?: (Files.size(this).toInt() - offset) @@ -58,7 +58,7 @@ fun Path.readEnvelope(format: EnvelopeFormat): Envelope { */ @Suppress("UNCHECKED_CAST") @DFExperimental -inline fun <reified T : Any> IOPlugin.resolveIOFormat(): IOFormat<T>? { +public inline fun <reified T : Any> IOPlugin.resolveIOFormat(): IOFormat<T>? { return ioFormatFactories.find { it.type.isSuperclassOf(T::class) } as IOFormat<T>? } @@ -66,7 +66,11 @@ inline fun <reified T : Any> IOPlugin.resolveIOFormat(): IOFormat<T>? { * Read file containing meta using given [formatOverride] or file extension to infer meta type. * If [path] is a directory search for file starting with `meta` in it */ -fun IOPlugin.readMetaFile(path: Path, formatOverride: MetaFormat? = null, descriptor: NodeDescriptor? = null): Meta { +public fun IOPlugin.readMetaFile( + path: Path, + formatOverride: MetaFormat? = null, + descriptor: NodeDescriptor? = null, +): Meta { if (!Files.exists(path)) error("Meta file $path does not exist") val actualPath: Path = if (Files.isDirectory(path)) { @@ -80,7 +84,7 @@ fun IOPlugin.readMetaFile(path: Path, formatOverride: MetaFormat? = null, descri val metaFormat = formatOverride ?: resolveMetaFormat(extension) ?: error("Can't resolve meta format $extension") return metaFormat.run { actualPath.read { - readMeta(descriptor) + readMeta(this, descriptor) } } } @@ -89,11 +93,11 @@ fun IOPlugin.readMetaFile(path: Path, formatOverride: MetaFormat? = null, descri * Write meta to file using [metaFormat]. If [path] is a directory, write a file with name equals name of [metaFormat]. * Like "meta.json" */ -fun IOPlugin.writeMetaFile( +public fun IOPlugin.writeMetaFile( path: Path, meta: Meta, metaFormat: MetaFormatFactory = JsonMetaFormat, - descriptor: NodeDescriptor? = null + descriptor: NodeDescriptor? = null, ) { val actualPath = if (Files.isDirectory(path)) { path.resolve("@" + metaFormat.name.toString()) @@ -102,7 +106,7 @@ fun IOPlugin.writeMetaFile( } metaFormat.run { actualPath.write { - writeMeta(meta, descriptor) + writeMeta(this, meta, descriptor) } } } @@ -111,7 +115,7 @@ fun IOPlugin.writeMetaFile( * Return inferred [EnvelopeFormat] if only one format could read given file. If no format accepts file, return null. If * multiple formats accepts file, throw an error. */ -fun IOPlugin.peekBinaryFormat(path: Path): EnvelopeFormat? { +public fun IOPlugin.peekBinaryFormat(path: Path): EnvelopeFormat? { val binary = path.asBinary() val formats = envelopeFormatFactories.mapNotNull { factory -> binary.read { @@ -126,8 +130,8 @@ fun IOPlugin.peekBinaryFormat(path: Path): EnvelopeFormat? { } } -val IOPlugin.Companion.META_FILE_NAME: String get() = "@meta" -val IOPlugin.Companion.DATA_FILE_NAME: String get() = "@data" +public val IOPlugin.Companion.META_FILE_NAME: String get() = "@meta" +public val IOPlugin.Companion.DATA_FILE_NAME: String get() = "@data" /** * Read and envelope from file if the file exists, return null if file does not exist. @@ -143,17 +147,18 @@ val IOPlugin.Companion.DATA_FILE_NAME: String get() = "@data" * Return null otherwise. */ @DFExperimental -fun IOPlugin.readEnvelopeFile( +public fun IOPlugin.readEnvelopeFile( path: Path, readNonEnvelopes: Boolean = false, - formatPeeker: IOPlugin.(Path) -> EnvelopeFormat? = IOPlugin::peekBinaryFormat + formatPeeker: IOPlugin.(Path) -> EnvelopeFormat? = IOPlugin::peekBinaryFormat, ): Envelope? { if (!Files.exists(path)) return null //read two-files directory if (Files.isDirectory(path)) { - val metaFile = Files.list(path).asSequence() - .singleOrNull { it.fileName.toString().startsWith(IOPlugin.META_FILE_NAME) } + val metaFile = Files.list(path).asSequence().singleOrNull { + it.fileName.toString().startsWith(IOPlugin.META_FILE_NAME) + } val meta = if (metaFile == null) { Meta.EMPTY @@ -182,9 +187,9 @@ fun IOPlugin.readEnvelopeFile( /** * Write a binary into file. Throws an error if file already exists */ -fun <T : Any> IOFormat<T>.writeToFile(path: Path, obj: T) { +public fun <T : Any> IOFormat<T>.writeToFile(path: Path, obj: T) { path.write { - writeObject(obj) + writeObject(this, obj) } } @@ -192,16 +197,14 @@ fun <T : Any> IOFormat<T>.writeToFile(path: Path, obj: T) { * Write envelope file to given [path] using [envelopeFormat] and optional [metaFormat] */ @DFExperimental -fun IOPlugin.writeEnvelopeFile( +public fun IOPlugin.writeEnvelopeFile( path: Path, envelope: Envelope, envelopeFormat: EnvelopeFormat = TaggedEnvelopeFormat, - metaFormat: MetaFormatFactory? = null + metaFormat: MetaFormatFactory? = null, ) { path.rewrite { - with(envelopeFormat) { - writeEnvelope(envelope, metaFormat ?: envelopeFormat.defaultMetaFormat) - } + envelopeFormat.writeEnvelope(this, envelope, metaFormat ?: envelopeFormat.defaultMetaFormat) } } @@ -209,10 +212,10 @@ fun IOPlugin.writeEnvelopeFile( * Write separate meta and data files to given directory [path] */ @DFExperimental -fun IOPlugin.writeEnvelopeDirectory( +public fun IOPlugin.writeEnvelopeDirectory( path: Path, envelope: Envelope, - metaFormat: MetaFormatFactory = JsonMetaFormat + metaFormat: MetaFormatFactory = JsonMetaFormat, ) { if (!Files.exists(path)) { Files.createDirectories(path) diff --git a/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/functionsJVM.kt b/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/functionsJVM.kt deleted file mode 100644 index ccd57c55..00000000 --- a/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/functionsJVM.kt +++ /dev/null @@ -1,28 +0,0 @@ -package hep.dataforge.io - -import hep.dataforge.io.functions.FunctionServer -import hep.dataforge.io.functions.function -import hep.dataforge.meta.Meta -import hep.dataforge.names.Name -import kotlin.reflect.KClass -import kotlin.reflect.full.isSuperclassOf - - -fun IOPlugin.resolveIOFormatName(type: KClass<*>): Name { - return ioFormatFactories.find { it.type.isSuperclassOf(type) }?.name - ?: error("Can't resolve IOFormat for type $type") -} - -inline fun <reified T : Any, reified R : Any> IOPlugin.generateFunctionMeta(functionName: String): Meta = Meta { - FunctionServer.FUNCTION_NAME_KEY put functionName - FunctionServer.INPUT_FORMAT_KEY put resolveIOFormatName(T::class).toString() - FunctionServer.OUTPUT_FORMAT_KEY put resolveIOFormatName(R::class).toString() -} - -inline fun <reified T : Any, reified R : Any> FunctionServer.function( - functionName: String -): (suspend (T) -> R) { - val plugin = context.plugins.get<IOPlugin>() ?: error("IO plugin not loaded") - val meta = plugin.generateFunctionMeta<T, R>(functionName) - return function(meta) -} \ No newline at end of file diff --git a/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/tcp/streams.kt b/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/streamsIO.kt similarity index 75% rename from dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/tcp/streams.kt rename to dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/streamsIO.kt index ec79eb22..ff392552 100644 --- a/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/tcp/streams.kt +++ b/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/streamsIO.kt @@ -1,4 +1,4 @@ -package hep.dataforge.io.tcp +package hep.dataforge.io import kotlinx.io.* import kotlinx.io.buffer.Buffer @@ -30,16 +30,16 @@ private class BlockingStreamInput(val source: InputStream) : Input() { } } -fun <R> InputStream.read(size: Int, block: Input.() -> R): R { +public fun <R> InputStream.read(size: Int, block: Input.() -> R): R { val buffer = ByteArray(size) read(buffer) return buffer.asBinary().read(block = block) } -fun <R> InputStream.read(block: Input.() -> R): R = asInput().block() +public fun <R> InputStream.read(block: Input.() -> R): R = asInput().block() -fun <R> InputStream.readBlocking(block: Input.() -> R): R = BlockingStreamInput(this).block() +public fun <R> InputStream.readBlocking(block: Input.() -> R): R = BlockingStreamInput(this).block() -inline fun OutputStream.write(block: Output.() -> Unit) { +public inline fun OutputStream.write(block: Output.() -> Unit) { asOutput().block() } \ No newline at end of file diff --git a/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/tcp/EnvelopeClient.kt b/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/tcp/EnvelopeClient.kt deleted file mode 100644 index 156acd89..00000000 --- a/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/tcp/EnvelopeClient.kt +++ /dev/null @@ -1,65 +0,0 @@ -package hep.dataforge.io.tcp - -import hep.dataforge.context.Context -import hep.dataforge.context.ContextAware -import hep.dataforge.io.* -import hep.dataforge.meta.Meta -import kotlinx.coroutines.asCoroutineDispatcher -import kotlinx.coroutines.withContext -import java.net.Socket -import java.util.concurrent.Executors -import kotlin.time.ExperimentalTime - -@ExperimentalTime -class EnvelopeClient( - override val context: Context, - val host: String, - val port: Int, - formatFactory: EnvelopeFormatFactory = TaggedEnvelopeFormat, - formatMeta: Meta = Meta.EMPTY -) : Responder, ContextAware { - - private val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher() - - private val format = formatFactory(formatMeta, context = context) - -// private var socket: SocketChannel? = null -// -// private fun getSocket(): Socket { -// val socket = socket ?: Socket(host, port).also { this.socket = it } -// return if (socket.isConnected) { -// socket -// } else { -// Socket(host, port).also { this.socket = it } -// } -// } - - suspend fun close() { - try { - respond( - Envelope { - type = EnvelopeServer.SHUTDOWN_ENVELOPE_TYPE - } - ) - } catch (ex: Exception) { - logger.error { ex } - } - } - - - override suspend fun respond(request: Envelope): Envelope = withContext(dispatcher) { - //val address = InetSocketAddress(host,port) - val socket = Socket(host, port) - val inputStream = socket.getInputStream() - val outputStream = socket.getOutputStream() - format.run { - outputStream.write { - writeObject(request) - } - logger.debug { "Sent request with type ${request.type} to ${socket.remoteSocketAddress}" } - val res = inputStream.readBlocking { readObject() } - logger.debug { "Received response with type ${res.type} from ${socket.remoteSocketAddress}" } - return@withContext res - } - } -} \ No newline at end of file diff --git a/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/tcp/EnvelopeServer.kt b/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/tcp/EnvelopeServer.kt deleted file mode 100644 index b9569279..00000000 --- a/dataforge-io/src/jvmMain/kotlin/hep/dataforge/io/tcp/EnvelopeServer.kt +++ /dev/null @@ -1,103 +0,0 @@ -package hep.dataforge.io.tcp - -import hep.dataforge.context.Context -import hep.dataforge.context.ContextAware -import hep.dataforge.io.EnvelopeFormatFactory -import hep.dataforge.io.Responder -import hep.dataforge.io.TaggedEnvelopeFormat -import hep.dataforge.io.type -import hep.dataforge.meta.Meta -import kotlinx.coroutines.* -import java.net.ServerSocket -import java.net.Socket -import kotlin.concurrent.thread - -class EnvelopeServer( - override val context: Context, - val port: Int, - val responder: Responder, - val scope: CoroutineScope, - formatFactory: EnvelopeFormatFactory = TaggedEnvelopeFormat, - formatMeta: Meta = Meta.EMPTY -) : ContextAware { - - private var job: Job? = null - - private val format = formatFactory(formatMeta, context = context) - - fun start() { - if (job == null) { - logger.info { "Starting envelope server on port $port" } - job = scope.launch(Dispatchers.IO) { - val serverSocket = ServerSocket(port) - //TODO add handshake and format negotiation - while (isActive && !serverSocket.isClosed) { - val socket = serverSocket.accept() - logger.info { "Accepted connection from ${socket.remoteSocketAddress}" } - readSocket(socket) - } - } - } - } - - fun stop() { - logger.info { "Stopping envelope server on port $port" } - job?.cancel() - job = null - } - -// private fun CoroutineScope.readSocket(socket: Socket) { -// launch(Dispatchers.IO) { -// val input = socket.getInputStream().asInput() -// val output = socket.getOutputStream().asOutput() -// format.run { -// while (isActive && socket.isConnected) { -// val request = input.readThis() -// logger.debug { "Accepted request with type ${request.type} from ${socket.remoteSocketAddress}" } -// if (request.type == SHUTDOWN_ENVELOPE_TYPE) { -// //Echo shutdown command -// logger.info { "Accepted graceful shutdown signal from ${socket.inetAddress}" } -// socket.close() -// cancel("Graceful connection shutdown requested by client") -// } -// val response = responder.respond(request) -// output.writeThis(response) -// } -// } -// } -// } - - private fun readSocket(socket: Socket) { - thread { - val inputStream = socket.getInputStream() - val outputStream = socket.getOutputStream() - format.run { - while (socket.isConnected) { - val request = inputStream.readBlocking { readObject() } - logger.debug { "Accepted request with type ${request.type} from ${socket.remoteSocketAddress}" } - if (request.type == SHUTDOWN_ENVELOPE_TYPE) { - //Echo shutdown command - outputStream.write { - writeObject(request) - } - logger.info { "Accepted graceful shutdown signal from ${socket.inetAddress}" } - socket.close() - return@thread -// cancel("Graceful connection shutdown requested by client") - } - runBlocking { - val response = responder.respond(request) - outputStream.write { - writeObject(response) - } - logger.debug { "Sent response with type ${response.type} to ${socket.remoteSocketAddress}" } - } - } - } - } - } - - companion object { - const val SHUTDOWN_ENVELOPE_TYPE = "@shutdown" - } -} \ No newline at end of file diff --git a/dataforge-io/src/jvmTest/kotlin/hep/dataforge/io/tcp/EnvelopeServerTest.kt b/dataforge-io/src/jvmTest/kotlin/hep/dataforge/io/tcp/EnvelopeServerTest.kt deleted file mode 100644 index 48c108d4..00000000 --- a/dataforge-io/src/jvmTest/kotlin/hep/dataforge/io/tcp/EnvelopeServerTest.kt +++ /dev/null @@ -1,70 +0,0 @@ -package hep.dataforge.io.tcp - -import hep.dataforge.context.Global -import hep.dataforge.io.Envelope -import hep.dataforge.io.Responder -import hep.dataforge.io.TaggedEnvelopeFormat -import hep.dataforge.io.toByteArray -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.runBlocking -import kotlinx.io.writeDouble -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Timeout -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.time.ExperimentalTime - -@ExperimentalStdlibApi -object EchoResponder : Responder { - override suspend fun respond(request: Envelope): Envelope { - val string = TaggedEnvelopeFormat().run { toByteArray(request).decodeToString() } - println("ECHO:") - println(string) - return request - } -} - -@ExperimentalTime -@ExperimentalStdlibApi -class EnvelopeServerTest { - companion object { - @JvmStatic - val echoEnvelopeServer = EnvelopeServer(Global, 7778, EchoResponder, GlobalScope) - - @BeforeAll - @JvmStatic - fun start() { - echoEnvelopeServer.start() - } - - @AfterAll - @JvmStatic - fun close() { - echoEnvelopeServer.stop() - } - } - - @Test - @Timeout(1) - fun doEchoTest() { - val request = Envelope { - type = "test.echo" - meta { - "test.value" put 22 - } - data { - writeDouble(22.7) - } - } - val client = EnvelopeClient(Global, host = "localhost", port = 7778) - runBlocking { - val response = client.respond(request) - - - assertEquals(request.meta, response.meta) -// assertEquals(request.data?.toBytes()?.decodeToString(), response.data?.toBytes()?.decodeToString()) - client.close() - } - } -} \ No newline at end of file diff --git a/dataforge-meta/api/dataforge-meta.api b/dataforge-meta/api/dataforge-meta.api new file mode 100644 index 00000000..f4b8d3ed --- /dev/null +++ b/dataforge-meta/api/dataforge-meta.api @@ -0,0 +1,1015 @@ +public abstract class hep/dataforge/meta/AbstractMetaNode : hep/dataforge/meta/MetaBase, hep/dataforge/meta/MetaNode { + public fun <init> ()V + public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public abstract class hep/dataforge/meta/AbstractMutableMeta : hep/dataforge/meta/AbstractMetaNode, hep/dataforge/meta/MutableMeta { + public fun <init> ()V + protected final fun getChildren ()Ljava/util/Map; + public fun getItems ()Ljava/util/Map; + protected fun replaceItem (Lhep/dataforge/names/NameToken;Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/MetaItem;)V + public fun setItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V + protected final fun wrapItem (Lhep/dataforge/meta/MetaItem;)Lhep/dataforge/meta/MetaItem; + protected abstract fun wrapNode (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MutableMeta; +} + +public final class hep/dataforge/meta/Config : hep/dataforge/meta/AbstractMutableMeta, hep/dataforge/meta/ObservableMeta { + public static final field ConfigSerializer Lhep/dataforge/meta/Config$ConfigSerializer; + public fun <init> ()V + public synthetic fun empty$dataforge_meta ()Lhep/dataforge/meta/MutableMeta; + public fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V + public fun removeListener (Ljava/lang/Object;)V + public synthetic fun wrapNode (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MutableMeta; +} + +public final class hep/dataforge/meta/Config$ConfigSerializer : kotlinx/serialization/KSerializer { + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/meta/Config; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public final fun empty ()Lhep/dataforge/meta/Config; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lhep/dataforge/meta/Config;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + +public final class hep/dataforge/meta/ConfigKt { + public static final fun asConfig (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Config; + public static final fun get (Lhep/dataforge/meta/Config;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/MetaItem; +} + +public abstract interface class hep/dataforge/meta/Configurable { + public abstract fun getConfig ()Lhep/dataforge/meta/Config; +} + +public final class hep/dataforge/meta/ConfigurableKt { + public static final fun config (Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun config$default (Lhep/dataforge/meta/Configurable;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun configure (Lhep/dataforge/meta/Configurable;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Configurable; + public static final fun configure (Lhep/dataforge/meta/Configurable;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; +} + +public abstract interface annotation class hep/dataforge/meta/DFBuilder : java/lang/annotation/Annotation { +} + +public abstract interface annotation class hep/dataforge/meta/DFExperimental : java/lang/annotation/Annotation { +} + +public final class hep/dataforge/meta/GetIndexedKt { + public static final fun getIndexed (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/Name;)Ljava/util/Map; + public static final fun getIndexed (Lhep/dataforge/meta/Meta;Ljava/lang/String;)Ljava/util/Map; + public static final fun getIndexed (Lhep/dataforge/meta/MetaNode;Lhep/dataforge/names/Name;)Ljava/util/Map; + public static final fun getIndexed (Lhep/dataforge/meta/MetaNode;Ljava/lang/String;)Ljava/util/Map; +} + +public final class hep/dataforge/meta/ItemDelegateKt { + public static final fun boolean (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static final fun boolean (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadOnlyProperty; + public static final fun boolean (Lhep/dataforge/meta/ItemProvider;ZLhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun boolean$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun boolean$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun boolean$default (Lhep/dataforge/meta/ItemProvider;ZLhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun convert (Lkotlin/properties/ReadOnlyProperty;Lhep/dataforge/meta/transformations/MetaConverter;)Lkotlin/properties/ReadOnlyProperty; + public static final fun convert (Lkotlin/properties/ReadOnlyProperty;Lhep/dataforge/meta/transformations/MetaConverter;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadOnlyProperty; + public static final fun convert (Lkotlin/properties/ReadOnlyProperty;Lkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadOnlyProperty; + public static final fun double (Lhep/dataforge/meta/ItemProvider;DLhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static final fun double (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun double$default (Lhep/dataforge/meta/ItemProvider;DLhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun double$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun float (Lhep/dataforge/meta/ItemProvider;FLhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static final fun float (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun float$default (Lhep/dataforge/meta/ItemProvider;FLhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun float$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun int (Lhep/dataforge/meta/ItemProvider;ILhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static final fun int (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun int$default (Lhep/dataforge/meta/ItemProvider;ILhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun int$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun item (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun item$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun long (Lhep/dataforge/meta/ItemProvider;JLhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static final fun long (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun long$default (Lhep/dataforge/meta/ItemProvider;JLhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun long$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun node (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun node$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun number (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static final fun number (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadOnlyProperty; + public static final fun number (Lhep/dataforge/meta/ItemProvider;Ljava/lang/Number;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun number$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun number$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun number$default (Lhep/dataforge/meta/ItemProvider;Ljava/lang/Number;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun string (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static final fun string (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadOnlyProperty; + public static final fun string (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun string$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun string$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun string$default (Lhep/dataforge/meta/ItemProvider;Ljava/lang/String;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; + public static final fun value (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadOnlyProperty; + public static synthetic fun value$default (Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadOnlyProperty; +} + +public abstract interface class hep/dataforge/meta/ItemProvider { + public static final field Companion Lhep/dataforge/meta/ItemProvider$Companion; + public abstract fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; +} + +public final class hep/dataforge/meta/ItemProvider$Companion { + public final fun getEMPTY ()Lhep/dataforge/meta/ItemProvider; +} + +public final class hep/dataforge/meta/JsonMeta : hep/dataforge/meta/MetaBase { + public static final field Companion Lhep/dataforge/meta/JsonMeta$Companion; + public static final field JSON_ARRAY_KEY Ljava/lang/String; + public fun <init> (Lkotlinx/serialization/json/JsonObject;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public synthetic fun <init> (Lkotlinx/serialization/json/JsonObject;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getItems ()Ljava/util/Map; +} + +public final class hep/dataforge/meta/JsonMeta$Companion { +} + +public final class hep/dataforge/meta/JsonMetaKt { + public static final fun toJson (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lkotlinx/serialization/json/JsonObject; + public static final fun toJson (Lhep/dataforge/values/Value;Lhep/dataforge/meta/descriptors/ValueDescriptor;)Lkotlinx/serialization/json/JsonElement; + public static synthetic fun toJson$default (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)Lkotlinx/serialization/json/JsonObject; + public static synthetic fun toJson$default (Lhep/dataforge/values/Value;Lhep/dataforge/meta/descriptors/ValueDescriptor;ILjava/lang/Object;)Lkotlinx/serialization/json/JsonElement; + public static final fun toMeta (Lkotlinx/serialization/json/JsonObject;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/JsonMeta; + public static synthetic fun toMeta$default (Lkotlinx/serialization/json/JsonObject;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)Lhep/dataforge/meta/JsonMeta; + public static final fun toMetaItem (Lkotlinx/serialization/json/JsonElement;Lhep/dataforge/meta/descriptors/ItemDescriptor;)Lhep/dataforge/meta/MetaItem; + public static synthetic fun toMetaItem$default (Lkotlinx/serialization/json/JsonElement;Lhep/dataforge/meta/descriptors/ItemDescriptor;ILjava/lang/Object;)Lhep/dataforge/meta/MetaItem; + public static final fun toValue (Lkotlinx/serialization/json/JsonPrimitive;Lhep/dataforge/meta/descriptors/ValueDescriptor;)Lhep/dataforge/values/Value; +} + +public final class hep/dataforge/meta/Laminate : hep/dataforge/meta/MetaBase { + public static final field Companion Lhep/dataforge/meta/Laminate$Companion; + public fun <init> (Ljava/util/List;)V + public fun getItems ()Ljava/util/Map; + public final fun getLayers ()Ljava/util/List; + public final fun merge ()Lhep/dataforge/meta/SealedMeta; +} + +public final class hep/dataforge/meta/Laminate$Companion { + public final fun getMergeRule ()Lkotlin/jvm/functions/Function1; + public final fun getReplaceRule ()Lkotlin/jvm/functions/Function1; +} + +public final class hep/dataforge/meta/LaminateKt { + public static final fun Laminate ([Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Laminate; + public static final fun getFirst (Lhep/dataforge/meta/Laminate;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public static final fun withBottom (Lhep/dataforge/meta/Laminate;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Laminate; + public static final fun withTop (Lhep/dataforge/meta/Laminate;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Laminate; +} + +public final class hep/dataforge/meta/MapMetaKt { + public static final fun toMap (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Ljava/util/Map; + public static synthetic fun toMap$default (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)Ljava/util/Map; + public static final fun toMeta (Ljava/util/Map;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Meta; + public static synthetic fun toMeta$default (Ljava/util/Map;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILjava/lang/Object;)Lhep/dataforge/meta/Meta; +} + +public abstract interface class hep/dataforge/meta/Meta : hep/dataforge/meta/ItemProvider, hep/dataforge/meta/MetaRepr { + public static final field Companion Lhep/dataforge/meta/Meta$Companion; + public static final field TYPE Ljava/lang/String; + public static final field VALUE_KEY Ljava/lang/String; + public abstract fun equals (Ljava/lang/Object;)Z + public abstract fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public abstract fun getItems ()Ljava/util/Map; + public abstract fun hashCode ()I + public abstract fun toMeta ()Lhep/dataforge/meta/Meta; + public abstract fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/meta/Meta$Companion { + public static final field TYPE Ljava/lang/String; + public static final field VALUE_KEY Ljava/lang/String; + public final fun getEMPTY ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/meta/Meta$DefaultImpls { + public static fun getItem (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public static fun toMeta (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Meta; +} + +public abstract class hep/dataforge/meta/MetaBase : hep/dataforge/meta/Meta { + public fun <init> ()V + public fun equals (Ljava/lang/Object;)Z + public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public fun hashCode ()I + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/meta/MetaBuilder : hep/dataforge/meta/AbstractMutableMeta { + public fun <init> ()V + public synthetic fun empty$dataforge_meta ()Lhep/dataforge/meta/MutableMeta; + public final fun put (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V + public final fun put (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaRepr;)V + public final fun put (Lhep/dataforge/names/Name;Lhep/dataforge/values/Value;)V + public final fun put (Lhep/dataforge/names/Name;Ljava/lang/Boolean;)V + public final fun put (Lhep/dataforge/names/Name;Ljava/lang/Enum;)V + public final fun put (Lhep/dataforge/names/Name;Ljava/lang/Number;)V + public final fun put (Lhep/dataforge/names/Name;Ljava/lang/String;)V + public final fun put (Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V + public final fun put (Ljava/lang/String;Lhep/dataforge/meta/Meta;)V + public final fun put (Ljava/lang/String;Lhep/dataforge/meta/MetaItem;)V + public final fun put (Ljava/lang/String;Lhep/dataforge/meta/MetaRepr;)V + public final fun put (Ljava/lang/String;Lhep/dataforge/values/Value;)V + public final fun put (Ljava/lang/String;Ljava/lang/Boolean;)V + public final fun put (Ljava/lang/String;Ljava/lang/Enum;)V + public final fun put (Ljava/lang/String;Ljava/lang/Number;)V + public final fun put (Ljava/lang/String;Ljava/lang/String;)V + public final fun put (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public final fun put (Ljava/lang/String;[D)V + public final fun putMetas (Lhep/dataforge/names/Name;Ljava/lang/Iterable;)V + public final fun putMetas (Ljava/lang/String;Ljava/lang/Iterable;)V + public final fun putNumbers (Ljava/lang/String;Ljava/lang/Iterable;)V + public final fun putStrings (Ljava/lang/String;Ljava/lang/Iterable;)V + public final fun putValues (Lhep/dataforge/names/Name;Ljava/lang/Iterable;)V + public final fun putValues (Ljava/lang/String;Ljava/lang/Iterable;)V + public synthetic fun wrapNode (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MutableMeta; +} + +public final class hep/dataforge/meta/MetaBuilderKt { + public static final fun Meta (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MetaBuilder; + public static final fun builder (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MetaBuilder; + public static final fun edit (Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MetaBuilder; +} + +public abstract class hep/dataforge/meta/MetaItem { + public static final field Companion Lhep/dataforge/meta/MetaItem$Companion; + public abstract fun equals (Ljava/lang/Object;)Z + public abstract fun hashCode ()I +} + +public final class hep/dataforge/meta/MetaItem$Companion { + public final fun of (Ljava/lang/Object;)Lhep/dataforge/meta/MetaItem; + public final fun serializer (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer; +} + +public final class hep/dataforge/meta/MetaItem$NodeItem : hep/dataforge/meta/MetaItem { + public static final field Companion Lhep/dataforge/meta/MetaItem$NodeItem$Companion; + public fun <init> (Lhep/dataforge/meta/Meta;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getNode ()Lhep/dataforge/meta/Meta; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/meta/MetaItem$NodeItem$Companion { + public final fun serializer (Lkotlinx/serialization/KSerializer;)Lkotlinx/serialization/KSerializer; +} + +public final class hep/dataforge/meta/MetaItem$ValueItem : hep/dataforge/meta/MetaItem { + public static final field Companion Lhep/dataforge/meta/MetaItem$ValueItem$Companion; + public fun <init> (Lhep/dataforge/values/Value;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getValue ()Lhep/dataforge/values/Value; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/meta/MetaItem$ValueItem$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + +public final class hep/dataforge/meta/MetaItemSerializer : kotlinx/serialization/KSerializer { + public static final field INSTANCE Lhep/dataforge/meta/MetaItemSerializer; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/meta/MetaItem; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lhep/dataforge/meta/MetaItem;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V +} + +public final class hep/dataforge/meta/MetaKt { + public static final fun asMetaItem (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/MetaItem$NodeItem; + public static final fun asMetaItem (Lhep/dataforge/values/Value;)Lhep/dataforge/meta/MetaItem$ValueItem; + public static final fun get (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public static final fun get (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/MetaItem; + public static final fun get (Lhep/dataforge/meta/Meta;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem; + public static final fun get (Lhep/dataforge/meta/MetaNode;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public static final fun get (Lhep/dataforge/meta/MetaNode;Lhep/dataforge/names/NameToken;)Lhep/dataforge/meta/MetaItem; + public static final fun get (Lhep/dataforge/meta/MetaNode;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem; + public static final fun getBoolean (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Boolean; + public static final fun getDouble (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Double; + public static final fun getFloat (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Float; + public static final fun getInt (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Integer; + public static final fun getLong (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Long; + public static final fun getNode (Lhep/dataforge/meta/MetaItem;)Lhep/dataforge/meta/Meta; + public static final fun getNumber (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Number; + public static final fun getShort (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Short; + public static final fun getString (Lhep/dataforge/meta/MetaItem;)Ljava/lang/String; + public static final fun getStringList (Lhep/dataforge/meta/MetaItem;)Ljava/util/List; + public static final fun getValue (Lhep/dataforge/meta/MetaItem;)Lhep/dataforge/values/Value; + public static final fun isEmpty (Lhep/dataforge/meta/Meta;)Z + public static final fun iterator (Lhep/dataforge/meta/Meta;)Ljava/util/Iterator; + public static final fun seal (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/SealedMeta; + public static final fun seal (Lhep/dataforge/meta/MetaItem;)Lhep/dataforge/meta/MetaItem; + public static final fun sequence (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; + public static final fun values (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; +} + +public final class hep/dataforge/meta/MetaListener { + public fun <init> (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V + public synthetic fun <init> (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/Object; + public final fun component2 ()Lkotlin/jvm/functions/Function3; + public final fun copy (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/meta/MetaListener; + public static synthetic fun copy$default (Lhep/dataforge/meta/MetaListener;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/meta/MetaListener; + public fun equals (Ljava/lang/Object;)Z + public final fun getAction ()Lkotlin/jvm/functions/Function3; + public final fun getOwner ()Ljava/lang/Object; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public abstract interface class hep/dataforge/meta/MetaNode : hep/dataforge/meta/Meta { + public abstract fun getItems ()Ljava/util/Map; +} + +public final class hep/dataforge/meta/MetaNode$DefaultImpls { + public static fun getItem (Lhep/dataforge/meta/MetaNode;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public static fun toMeta (Lhep/dataforge/meta/MetaNode;)Lhep/dataforge/meta/Meta; +} + +public abstract interface class hep/dataforge/meta/MetaRepr { + public abstract fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/meta/MetaSerializer : kotlinx/serialization/KSerializer { + public static final field INSTANCE Lhep/dataforge/meta/MetaSerializer; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/meta/Meta; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lhep/dataforge/meta/Meta;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V +} + +public final class hep/dataforge/meta/MetaWithDefault : hep/dataforge/meta/MetaBase { + public fun <init> (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)V + public final fun getDefault ()Lhep/dataforge/meta/ItemProvider; + public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public fun getItems ()Ljava/util/Map; + public final fun getMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/meta/MetaWithDefaultKt { + public static final fun withDefault (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MetaWithDefault; +} + +public final class hep/dataforge/meta/MutableItemDelegateKt { + public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty; + public static final fun boolean (Lhep/dataforge/meta/MutableItemProvider;ZLhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun boolean$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun boolean$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun boolean$default (Lhep/dataforge/meta/MutableItemProvider;ZLhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun convert (Lkotlin/properties/ReadWriteProperty;Lhep/dataforge/meta/transformations/MetaConverter;)Lkotlin/properties/ReadWriteProperty; + public static final fun convert (Lkotlin/properties/ReadWriteProperty;Lhep/dataforge/meta/transformations/MetaConverter;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty; + public static final fun convert (Lkotlin/properties/ReadWriteProperty;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadWriteProperty; + public static final fun double (Lhep/dataforge/meta/MutableItemProvider;DLhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun double (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun double$default (Lhep/dataforge/meta/MutableItemProvider;DLhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun double$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun doubleArray (Lhep/dataforge/meta/MutableItemProvider;[DLhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun doubleArray$default (Lhep/dataforge/meta/MutableItemProvider;[DLhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun float (Lhep/dataforge/meta/MutableItemProvider;FLhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun float (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun float$default (Lhep/dataforge/meta/MutableItemProvider;FLhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun float$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun int (Lhep/dataforge/meta/MutableItemProvider;ILhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun int (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun int$default (Lhep/dataforge/meta/MutableItemProvider;ILhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun int$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun item (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun item$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun listValue (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun listValue$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun long (Lhep/dataforge/meta/MutableItemProvider;JLhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun long (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun long$default (Lhep/dataforge/meta/MutableItemProvider;JLhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun long$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun number (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun number (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty; + public static final fun number (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/Number;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun number$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun number$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun number$default (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/Number;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun numberList (Lhep/dataforge/meta/MutableItemProvider;[Ljava/lang/Number;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun numberList$default (Lhep/dataforge/meta/MutableItemProvider;[Ljava/lang/Number;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun string (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun string (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty; + public static final fun string (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun string$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun string$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun string$default (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun stringList (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun stringList (Lhep/dataforge/meta/MutableItemProvider;[Ljava/lang/String;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun stringList$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun stringList$default (Lhep/dataforge/meta/MutableItemProvider;[Ljava/lang/String;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun value (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun value (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun value$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun value$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; +} + +public abstract interface class hep/dataforge/meta/MutableItemProvider : hep/dataforge/meta/ItemProvider { + public abstract fun setItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V +} + +public final class hep/dataforge/meta/MutableItemProviderKt { + public static final fun getItem (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;)Lhep/dataforge/meta/MetaItem; + public static final fun node (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun node$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun remove (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;)V + public static final fun remove (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Iterable;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Object;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/NameToken;Ljava/lang/Object;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Ljava/lang/Iterable;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Ljava/lang/Object;)V + public static final fun set (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V + public static final fun setIndexed (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun setIndexed$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + public static final fun setIndexedItems (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun setIndexedItems$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + public static final fun setItem (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Lhep/dataforge/meta/MetaItem;)V + public static final fun setNode (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V + public static final fun setNode (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Lhep/dataforge/meta/Meta;)V + public static final fun setValue (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/names/Name;Lhep/dataforge/values/Value;)V + public static final fun setValue (Lhep/dataforge/meta/MutableItemProvider;Ljava/lang/String;Lhep/dataforge/values/Value;)V +} + +public abstract interface class hep/dataforge/meta/MutableMeta : hep/dataforge/meta/MetaNode, hep/dataforge/meta/MutableItemProvider { + public abstract fun getItems ()Ljava/util/Map; +} + +public final class hep/dataforge/meta/MutableMeta$DefaultImpls { + public static fun getItem (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public static fun toMeta (Lhep/dataforge/meta/MutableMeta;)Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/meta/MutableMetaKt { + public static final fun append (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/names/Name;Ljava/lang/Object;)V + public static final fun append (Lhep/dataforge/meta/MutableMeta;Ljava/lang/String;Ljava/lang/Object;)V + public static final fun edit (Lhep/dataforge/meta/AbstractMutableMeta;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V + public static final fun update (Lhep/dataforge/meta/MutableMeta;Lhep/dataforge/meta/Meta;)V +} + +public abstract interface class hep/dataforge/meta/ObservableMeta : hep/dataforge/meta/Meta { + public abstract fun onChange (Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)V + public abstract fun removeListener (Ljava/lang/Object;)V +} + +public final class hep/dataforge/meta/ObservableMeta$DefaultImpls { + public static fun getItem (Lhep/dataforge/meta/ObservableMeta;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public static fun toMeta (Lhep/dataforge/meta/ObservableMeta;)Lhep/dataforge/meta/Meta; +} + +public class hep/dataforge/meta/Scheme : hep/dataforge/meta/Configurable, hep/dataforge/meta/MetaRepr, hep/dataforge/meta/MutableItemProvider, hep/dataforge/meta/descriptors/Described { + public fun <init> ()V + public fun <init> (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/descriptors/NodeDescriptor;)V + public synthetic fun <init> (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;Lhep/dataforge/meta/descriptors/NodeDescriptor;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getConfig ()Lhep/dataforge/meta/Config; + public final fun getDefaultItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public fun getDefaultLayer ()Lhep/dataforge/meta/Meta; + public synthetic fun getDescriptor ()Lhep/dataforge/meta/descriptors/ItemDescriptor; + public fun getDescriptor ()Lhep/dataforge/meta/descriptors/NodeDescriptor; + public fun getItem (Lhep/dataforge/names/Name;)Lhep/dataforge/meta/MetaItem; + public final fun isEmpty ()Z + public fun setItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)V + public fun toMeta ()Lhep/dataforge/meta/Laminate; + public synthetic fun toMeta ()Lhep/dataforge/meta/Meta; + public final fun validateItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z +} + +public final class hep/dataforge/meta/SchemeKt { + public static final fun asScheme (Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Scheme; + public static final fun invoke (Lhep/dataforge/meta/Scheme;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Scheme; + public static final fun toScheme (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; + public static synthetic fun toScheme$default (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/meta/MutableItemProvider; +} + +public class hep/dataforge/meta/SchemeSpec : hep/dataforge/meta/Specification, hep/dataforge/meta/descriptors/Described { + public fun <init> (Lkotlin/jvm/functions/Function0;)V + public fun <init> (Lkotlin/jvm/functions/Function3;)V + public synthetic fun empty ()Lhep/dataforge/meta/MutableItemProvider; + public fun empty ()Lhep/dataforge/meta/Scheme; + public synthetic fun getDescriptor ()Lhep/dataforge/meta/descriptors/ItemDescriptor; + public fun getDescriptor ()Lhep/dataforge/meta/descriptors/NodeDescriptor; + public synthetic fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; + public final fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Scheme; + public synthetic fun read (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; + public fun read (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme; + public synthetic fun wrap (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; + public fun wrap (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/Scheme; +} + +public final class hep/dataforge/meta/SealedMeta : hep/dataforge/meta/AbstractMetaNode { + public fun getItems ()Ljava/util/Map; +} + +public abstract interface class hep/dataforge/meta/Specification { + public abstract fun empty ()Lhep/dataforge/meta/MutableItemProvider; + public abstract fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; + public abstract fun read (Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; + public abstract fun wrap (Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; +} + +public final class hep/dataforge/meta/Specification$DefaultImpls { + public static fun empty (Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider; + public static fun invoke (Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; + public static synthetic fun read$default (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Meta;Lhep/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lhep/dataforge/meta/MutableItemProvider; + public static fun wrap (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;)Lhep/dataforge/meta/MutableItemProvider; + public static synthetic fun wrap$default (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Config;Lhep/dataforge/meta/ItemProvider;ILjava/lang/Object;)Lhep/dataforge/meta/MutableItemProvider; +} + +public final class hep/dataforge/meta/SpecificationKt { + public static final fun configSpec (Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider; + public static final fun configure (Lhep/dataforge/meta/MetaRepr;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MetaRepr; + public static final fun createStyle (Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Meta; + public static final fun spec (Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/Specification;)Lhep/dataforge/meta/MutableItemProvider; + public static final fun spec (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Scheme;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static final fun spec (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/names/Name;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun spec$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Scheme;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static synthetic fun spec$default (Lhep/dataforge/meta/MutableItemProvider;Lhep/dataforge/meta/Specification;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lkotlin/properties/ReadWriteProperty; + public static final fun update (Lhep/dataforge/meta/Configurable;Lhep/dataforge/meta/Specification;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/Configurable; + public static final fun update (Lhep/dataforge/meta/Specification;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/MutableItemProvider; +} + +public abstract interface class hep/dataforge/meta/descriptors/Described { + public static final field Companion Lhep/dataforge/meta/descriptors/Described$Companion; + public abstract fun getDescriptor ()Lhep/dataforge/meta/descriptors/ItemDescriptor; +} + +public final class hep/dataforge/meta/descriptors/Described$Companion { +} + +public final class hep/dataforge/meta/descriptors/DescriptorMetaKt { + public static final fun defaultItem (Lhep/dataforge/meta/descriptors/ItemDescriptor;)Lhep/dataforge/meta/MetaItem; + public static final fun defaultMeta (Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/Laminate; +} + +public abstract class hep/dataforge/meta/descriptors/ItemDescriptor { + public static final field Companion Lhep/dataforge/meta/descriptors/ItemDescriptor$Companion; + public static final field DEFAULT_INDEX_KEY Ljava/lang/String; + public synthetic fun <init> (Lhep/dataforge/meta/Config;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getAttributes ()Lhep/dataforge/meta/Config; + public final fun getConfig ()Lhep/dataforge/meta/Config; + public final fun getIndexKey ()Ljava/lang/String; + public final fun getInfo ()Ljava/lang/String; + public final fun getMultiple ()Z + public abstract fun getRequired ()Z + public final fun setAttributes (Lhep/dataforge/meta/Config;)V + public final fun setIndexKey (Ljava/lang/String;)V + public final fun setInfo (Ljava/lang/String;)V + public final fun setMultiple (Z)V + public abstract fun setRequired (Z)V +} + +public final class hep/dataforge/meta/descriptors/ItemDescriptor$Companion { +} + +public final class hep/dataforge/meta/descriptors/ItemDescriptorKt { + public static final fun attributes (Lhep/dataforge/meta/descriptors/ItemDescriptor;Lkotlin/jvm/functions/Function1;)V + public static final fun get (Lhep/dataforge/meta/descriptors/ItemDescriptor;Lhep/dataforge/names/Name;)Lhep/dataforge/meta/descriptors/ItemDescriptor; + public static final fun get (Lhep/dataforge/meta/descriptors/ItemDescriptor;Ljava/lang/String;)Lhep/dataforge/meta/descriptors/ItemDescriptor; + public static final fun plus (Lhep/dataforge/meta/descriptors/NodeDescriptor;Lhep/dataforge/meta/descriptors/NodeDescriptor;)Lhep/dataforge/meta/descriptors/NodeDescriptor; + public static final fun validateItem (Lhep/dataforge/meta/descriptors/ItemDescriptor;Lhep/dataforge/meta/MetaItem;)Z +} + +public final class hep/dataforge/meta/descriptors/NodeDescriptor : hep/dataforge/meta/descriptors/ItemDescriptor { + public static final field Companion Lhep/dataforge/meta/descriptors/NodeDescriptor$Companion; + public fun <init> ()V + public fun <init> (Lhep/dataforge/meta/Config;)V + public synthetic fun <init> (Lhep/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getDefault ()Lhep/dataforge/meta/Config; + public final fun getItems ()Ljava/util/Map; + public final fun getNodes ()Ljava/util/Map; + public fun getRequired ()Z + public final fun getValues ()Ljava/util/Map; + public final fun item (Lhep/dataforge/names/Name;Lhep/dataforge/meta/descriptors/ItemDescriptor;)V + public final fun item (Ljava/lang/String;Lhep/dataforge/meta/descriptors/ItemDescriptor;)V + public final fun node (Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V + public final fun node (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public final fun setDefault (Lhep/dataforge/meta/Config;)V + public fun setRequired (Z)V + public final fun value (Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V + public final fun value (Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V +} + +public final class hep/dataforge/meta/descriptors/NodeDescriptor$Companion { + public final fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/descriptors/NodeDescriptor; +} + +public final class hep/dataforge/meta/descriptors/ValueDescriptor : hep/dataforge/meta/descriptors/ItemDescriptor { + public fun <init> ()V + public fun <init> (Lhep/dataforge/meta/Config;)V + public synthetic fun <init> (Lhep/dataforge/meta/Config;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun allow ([Ljava/lang/Object;)V + public final fun default (Ljava/lang/Object;)V + public final fun getAllowedValues ()Ljava/util/List; + public final fun getDefault ()Lhep/dataforge/values/Value; + public fun getRequired ()Z + public final fun getType ()Ljava/util/List; + public final fun isAllowedValue (Lhep/dataforge/values/Value;)Z + public final fun setAllowedValues (Ljava/util/List;)V + public final fun setDefault (Lhep/dataforge/values/Value;)V + public fun setRequired (Z)V + public final fun setType (Ljava/util/List;)V + public final fun type ([Lhep/dataforge/values/ValueType;)V +} + +public final class hep/dataforge/meta/transformations/KeepTransformationRule : hep/dataforge/meta/transformations/TransformationRule { + public fun <init> (Lkotlin/jvm/functions/Function1;)V + public final fun component1 ()Lkotlin/jvm/functions/Function1; + public final fun copy (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/transformations/KeepTransformationRule; + public static synthetic fun copy$default (Lhep/dataforge/meta/transformations/KeepTransformationRule;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/meta/transformations/KeepTransformationRule; + public fun equals (Ljava/lang/Object;)Z + public final fun getSelector ()Lkotlin/jvm/functions/Function1; + public fun hashCode ()I + public fun matches (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z + public fun selectItems (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; + public fun toString ()Ljava/lang/String; + public fun transformItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/MutableMeta;)V +} + +public abstract interface class hep/dataforge/meta/transformations/MetaConverter { + public static final field Companion Lhep/dataforge/meta/transformations/MetaConverter$Companion; + public abstract fun itemToObject (Lhep/dataforge/meta/MetaItem;)Ljava/lang/Object; + public abstract fun objectToMetaItem (Ljava/lang/Object;)Lhep/dataforge/meta/MetaItem; +} + +public final class hep/dataforge/meta/transformations/MetaConverter$Companion { + public final fun getBoolean ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getDouble ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getFloat ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getInt ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getItem ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getLong ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getMeta ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getNumber ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getString ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun getValue ()Lhep/dataforge/meta/transformations/MetaConverter; + public final fun valueList (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/meta/transformations/MetaConverter; + public static synthetic fun valueList$default (Lhep/dataforge/meta/transformations/MetaConverter$Companion;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/meta/transformations/MetaConverter; +} + +public final class hep/dataforge/meta/transformations/MetaConverterKt { + public static final fun metaToObject (Lhep/dataforge/meta/transformations/MetaConverter;Lhep/dataforge/meta/Meta;)Ljava/lang/Object; + public static final fun nullableItemToObject (Lhep/dataforge/meta/transformations/MetaConverter;Lhep/dataforge/meta/MetaItem;)Ljava/lang/Object; + public static final fun nullableObjectToMetaItem (Lhep/dataforge/meta/transformations/MetaConverter;Ljava/lang/Object;)Lhep/dataforge/meta/MetaItem; + public static final fun valueToObject (Lhep/dataforge/meta/transformations/MetaConverter;Lhep/dataforge/values/Value;)Ljava/lang/Object; +} + +public final class hep/dataforge/meta/transformations/MetaTransformation { + public static final field Companion Lhep/dataforge/meta/transformations/MetaTransformation$Companion; + public static final fun apply-impl (Ljava/util/Collection;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Meta; + public static final fun bind-impl (Ljava/util/Collection;Lhep/dataforge/meta/Config;Lhep/dataforge/meta/MutableMeta;)V + public static final synthetic fun box-impl (Ljava/util/Collection;)Lhep/dataforge/meta/transformations/MetaTransformation; + public static fun constructor-impl (Ljava/util/Collection;)Ljava/util/Collection; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl (Ljava/util/Collection;Ljava/lang/Object;)Z + public static final fun equals-impl0 (Ljava/util/Collection;Ljava/util/Collection;)Z + public static final fun generate-impl (Ljava/util/Collection;Lhep/dataforge/meta/Config;)Lhep/dataforge/meta/ObservableMeta; + public static final fun generate-impl (Ljava/util/Collection;Lhep/dataforge/meta/Meta;)Lhep/dataforge/meta/Meta; + public final fun getTransformations ()Ljava/util/Collection; + public fun hashCode ()I + public static fun hashCode-impl (Ljava/util/Collection;)I + public fun toString ()Ljava/lang/String; + public static fun toString-impl (Ljava/util/Collection;)Ljava/lang/String; + public final synthetic fun unbox-impl ()Ljava/util/Collection; +} + +public final class hep/dataforge/meta/transformations/MetaTransformation$Companion { + public final fun make-S5KKvQA (Lkotlin/jvm/functions/Function1;)Ljava/util/Collection; +} + +public final class hep/dataforge/meta/transformations/MetaTransformationBuilder { + public fun <init> ()V + public final fun build-S5KKvQA ()Ljava/util/Collection; + public final fun keep (Lhep/dataforge/names/Name;)V + public final fun keep (Ljava/lang/String;)V + public final fun keep (Lkotlin/jvm/functions/Function1;)V + public final fun move (Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)V + public static synthetic fun move$default (Lhep/dataforge/meta/transformations/MetaTransformationBuilder;Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V +} + +public final class hep/dataforge/meta/transformations/RegexItemTransformationRule : hep/dataforge/meta/transformations/TransformationRule { + public fun <init> (Lkotlin/text/Regex;Lkotlin/jvm/functions/Function4;)V + public final fun component1 ()Lkotlin/text/Regex; + public final fun component2 ()Lkotlin/jvm/functions/Function4; + public final fun copy (Lkotlin/text/Regex;Lkotlin/jvm/functions/Function4;)Lhep/dataforge/meta/transformations/RegexItemTransformationRule; + public static synthetic fun copy$default (Lhep/dataforge/meta/transformations/RegexItemTransformationRule;Lkotlin/text/Regex;Lkotlin/jvm/functions/Function4;ILjava/lang/Object;)Lhep/dataforge/meta/transformations/RegexItemTransformationRule; + public fun equals (Ljava/lang/Object;)Z + public final fun getFrom ()Lkotlin/text/Regex; + public final fun getTransform ()Lkotlin/jvm/functions/Function4; + public fun hashCode ()I + public fun matches (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z + public fun selectItems (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; + public fun toString ()Ljava/lang/String; + public fun transformItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/MutableMeta;)V +} + +public final class hep/dataforge/meta/transformations/SingleItemTransformationRule : hep/dataforge/meta/transformations/TransformationRule { + public fun <init> (Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function3;)V + public final fun component1 ()Lhep/dataforge/names/Name; + public final fun component2 ()Lkotlin/jvm/functions/Function3; + public final fun copy (Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function3;)Lhep/dataforge/meta/transformations/SingleItemTransformationRule; + public static synthetic fun copy$default (Lhep/dataforge/meta/transformations/SingleItemTransformationRule;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function3;ILjava/lang/Object;)Lhep/dataforge/meta/transformations/SingleItemTransformationRule; + public fun equals (Ljava/lang/Object;)Z + public final fun getFrom ()Lhep/dataforge/names/Name; + public final fun getTransform ()Lkotlin/jvm/functions/Function3; + public fun hashCode ()I + public fun matches (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z + public fun selectItems (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; + public fun toString ()Ljava/lang/String; + public fun transformItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/MutableMeta;)V +} + +public abstract interface class hep/dataforge/meta/transformations/TransformationRule { + public abstract fun matches (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;)Z + public abstract fun selectItems (Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; + public abstract fun transformItem (Lhep/dataforge/names/Name;Lhep/dataforge/meta/MetaItem;Lhep/dataforge/meta/MutableMeta;)V +} + +public final class hep/dataforge/meta/transformations/TransformationRule$DefaultImpls { + public static fun selectItems (Lhep/dataforge/meta/transformations/TransformationRule;Lhep/dataforge/meta/Meta;)Lkotlin/sequences/Sequence; +} + +public final class hep/dataforge/names/Name { + public static final field Companion Lhep/dataforge/names/Name$Companion; + public static final field NAME_SEPARATOR Ljava/lang/String; + public fun <init> (Ljava/util/List;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getTokens ()Ljava/util/List; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/names/Name$Companion : kotlinx/serialization/KSerializer { + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/names/Name; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public final fun getEMPTY ()Lhep/dataforge/names/Name; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lhep/dataforge/names/Name;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + +public final class hep/dataforge/names/NameKt { + public static final fun appendLeft (Lhep/dataforge/names/Name;Ljava/lang/String;)Lhep/dataforge/names/Name; + public static final fun asName (Lhep/dataforge/names/NameToken;)Lhep/dataforge/names/Name; + public static final fun asName (Ljava/lang/String;)Lhep/dataforge/names/Name; + public static final fun cutFirst (Lhep/dataforge/names/Name;)Lhep/dataforge/names/Name; + public static final fun cutLast (Lhep/dataforge/names/Name;)Lhep/dataforge/names/Name; + public static final fun endsWith (Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;)Z + public static final fun endsWith (Lhep/dataforge/names/Name;Lhep/dataforge/names/NameToken;)Z + public static final fun firstOrNull (Lhep/dataforge/names/Name;)Lhep/dataforge/names/NameToken; + public static final fun get (Lhep/dataforge/names/Name;I)Lhep/dataforge/names/NameToken; + public static final fun get (Ljava/util/Map;Ljava/lang/String;)Ljava/lang/Object; + public static final fun get (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object; + public static synthetic fun get$default (Ljava/util/Map;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Ljava/lang/Object; + public static final fun getLength (Lhep/dataforge/names/Name;)I + public static final fun isEmpty (Lhep/dataforge/names/Name;)Z + public static final fun lastOrNull (Lhep/dataforge/names/Name;)Lhep/dataforge/names/NameToken; + public static final fun plus (Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;)Lhep/dataforge/names/Name; + public static final fun plus (Lhep/dataforge/names/Name;Lhep/dataforge/names/NameToken;)Lhep/dataforge/names/Name; + public static final fun plus (Lhep/dataforge/names/Name;Ljava/lang/String;)Lhep/dataforge/names/Name; + public static final fun plus (Lhep/dataforge/names/NameToken;Lhep/dataforge/names/Name;)Lhep/dataforge/names/Name; + public static final fun set (Ljava/util/Map;Ljava/lang/String;Ljava/lang/Object;)V + public static final fun startsWith (Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;)Z + public static final fun startsWith (Lhep/dataforge/names/Name;Lhep/dataforge/names/NameToken;)Z + public static final fun toName (Ljava/lang/String;)Lhep/dataforge/names/Name; + public static final fun withIndex (Lhep/dataforge/names/Name;Ljava/lang/String;)Lhep/dataforge/names/Name; +} + +public final class hep/dataforge/names/NameToken { + public static final field Companion Lhep/dataforge/names/NameToken$Companion; + public fun <init> (Ljava/lang/String;Ljava/lang/String;)V + public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun copy (Ljava/lang/String;Ljava/lang/String;)Lhep/dataforge/names/NameToken; + public static synthetic fun copy$default (Lhep/dataforge/names/NameToken;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lhep/dataforge/names/NameToken; + public fun equals (Ljava/lang/Object;)Z + public final fun getBody ()Ljava/lang/String; + public final fun getIndex ()Ljava/lang/String; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/names/NameToken$Companion : kotlinx/serialization/KSerializer { + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/names/NameToken; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lhep/dataforge/names/NameToken;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + +public final class hep/dataforge/names/NameTokenKt { + public static final fun hasIndex (Lhep/dataforge/names/NameToken;)Z + public static final fun withIndex (Lhep/dataforge/names/NameToken;Ljava/lang/String;)Lhep/dataforge/names/NameToken; +} + +public final class hep/dataforge/values/DoubleArrayValue : hep/dataforge/values/Value { + public fun <init> ([D)V + public fun equals (Ljava/lang/Object;)Z + public fun getList ()Ljava/util/List; + public fun getNumber ()Ljava/lang/Double; + public synthetic fun getNumber ()Ljava/lang/Number; + public fun getString ()Ljava/lang/String; + public fun getType ()Lhep/dataforge/values/ValueType; + public synthetic fun getValue ()Ljava/lang/Object; + public fun getValue ()[D + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/values/EnumValue : hep/dataforge/values/Value { + public fun <init> (Ljava/lang/Enum;)V + public fun equals (Ljava/lang/Object;)Z + public fun getList ()Ljava/util/List; + public fun getNumber ()Ljava/lang/Number; + public fun getString ()Ljava/lang/String; + public fun getType ()Lhep/dataforge/values/ValueType; + public fun getValue ()Ljava/lang/Enum; + public synthetic fun getValue ()Ljava/lang/Object; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/values/ExoticValuesKt { + public static final fun asValue ([D)Lhep/dataforge/values/Value; + public static final fun lazyParseValue (Ljava/lang/String;)Lhep/dataforge/values/LazyParsedValue; +} + +public final class hep/dataforge/values/False : hep/dataforge/values/Value { + public static final field INSTANCE Lhep/dataforge/values/False; + public fun equals (Ljava/lang/Object;)Z + public fun getList ()Ljava/util/List; + public fun getNumber ()Ljava/lang/Number; + public fun getString ()Ljava/lang/String; + public fun getType ()Lhep/dataforge/values/ValueType; + public fun getValue ()Ljava/lang/Object; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/values/LazyParsedValue : hep/dataforge/values/Value { + public fun <init> (Ljava/lang/String;)V + public fun equals (Ljava/lang/Object;)Z + public fun getList ()Ljava/util/List; + public fun getNumber ()Ljava/lang/Number; + public fun getString ()Ljava/lang/String; + public fun getType ()Lhep/dataforge/values/ValueType; + public fun getValue ()Ljava/lang/Object; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/values/ListValue : hep/dataforge/values/Value { + public fun <init> (Ljava/util/List;)V + public fun equals (Ljava/lang/Object;)Z + public fun getList ()Ljava/util/List; + public fun getNumber ()Ljava/lang/Number; + public fun getString ()Ljava/lang/String; + public fun getType ()Lhep/dataforge/values/ValueType; + public synthetic fun getValue ()Ljava/lang/Object; + public fun getValue ()Ljava/util/List; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/values/Null : hep/dataforge/values/Value { + public static final field INSTANCE Lhep/dataforge/values/Null; + public fun equals (Ljava/lang/Object;)Z + public fun getList ()Ljava/util/List; + public fun getNumber ()Ljava/lang/Number; + public fun getString ()Ljava/lang/String; + public fun getType ()Lhep/dataforge/values/ValueType; + public fun getValue ()Ljava/lang/Object; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/values/NumberValue : hep/dataforge/values/Value { + public fun <init> (Ljava/lang/Number;)V + public fun equals (Ljava/lang/Object;)Z + public fun getList ()Ljava/util/List; + public fun getNumber ()Ljava/lang/Number; + public fun getString ()Ljava/lang/String; + public fun getType ()Lhep/dataforge/values/ValueType; + public fun getValue ()Ljava/lang/Object; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/values/StringValue : hep/dataforge/values/Value { + public fun <init> (Ljava/lang/String;)V + public fun equals (Ljava/lang/Object;)Z + public fun getList ()Ljava/util/List; + public fun getNumber ()Ljava/lang/Number; + public fun getString ()Ljava/lang/String; + public fun getType ()Lhep/dataforge/values/ValueType; + public fun getValue ()Ljava/lang/Object; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/values/True : hep/dataforge/values/Value { + public static final field INSTANCE Lhep/dataforge/values/True; + public fun equals (Ljava/lang/Object;)Z + public fun getList ()Ljava/util/List; + public fun getNumber ()Ljava/lang/Number; + public fun getString ()Ljava/lang/String; + public fun getType ()Lhep/dataforge/values/ValueType; + public fun getValue ()Ljava/lang/Object; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public abstract interface class hep/dataforge/values/Value { + public static final field Companion Lhep/dataforge/values/Value$Companion; + public static final field TARGET Ljava/lang/String; + public abstract fun equals (Ljava/lang/Object;)Z + public abstract fun getList ()Ljava/util/List; + public abstract fun getNumber ()Ljava/lang/Number; + public abstract fun getString ()Ljava/lang/String; + public abstract fun getType ()Lhep/dataforge/values/ValueType; + public abstract fun getValue ()Ljava/lang/Object; + public abstract fun hashCode ()I +} + +public final class hep/dataforge/values/Value$Companion { + public static final field TARGET Ljava/lang/String; + public final fun of (Ljava/lang/Object;)Lhep/dataforge/values/Value; +} + +public final class hep/dataforge/values/Value$DefaultImpls { + public static fun getList (Lhep/dataforge/values/Value;)Ljava/util/List; +} + +public final class hep/dataforge/values/ValueExtensionsKt { + public static final fun getBoolean (Lhep/dataforge/values/Value;)Z + public static final fun getDouble (Lhep/dataforge/values/Value;)D + public static final fun getDoubleArray (Lhep/dataforge/values/Value;)[D + public static final fun getFloat (Lhep/dataforge/values/Value;)F + public static final fun getInt (Lhep/dataforge/values/Value;)I + public static final fun getLong (Lhep/dataforge/values/Value;)J + public static final fun getShort (Lhep/dataforge/values/Value;)S + public static final fun getStringList (Lhep/dataforge/values/Value;)Ljava/util/List; + public static final fun isList (Lhep/dataforge/values/Value;)Z + public static final fun isNull (Lhep/dataforge/values/Value;)Z + public static final fun toMeta (Lhep/dataforge/values/Value;)Lhep/dataforge/meta/MetaBuilder; +} + +public final class hep/dataforge/values/ValueKt { + public static final fun asValue (Ljava/lang/Enum;)Lhep/dataforge/values/Value; + public static final fun asValue (Ljava/lang/Iterable;)Lhep/dataforge/values/Value; + public static final fun asValue (Ljava/lang/Number;)Lhep/dataforge/values/Value; + public static final fun asValue (Ljava/lang/String;)Lhep/dataforge/values/Value; + public static final fun asValue (Z)Lhep/dataforge/values/Value; + public static final fun asValue ([B)Lhep/dataforge/values/Value; + public static final fun asValue ([F)Lhep/dataforge/values/Value; + public static final fun asValue ([I)Lhep/dataforge/values/Value; + public static final fun asValue ([J)Lhep/dataforge/values/Value; + public static final fun asValue ([S)Lhep/dataforge/values/Value; + public static final fun parseValue (Ljava/lang/String;)Lhep/dataforge/values/Value; +} + +public final class hep/dataforge/values/ValueSerializer : kotlinx/serialization/KSerializer { + public static final field INSTANCE Lhep/dataforge/values/ValueSerializer; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/values/Value; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lhep/dataforge/values/Value;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V +} + +public final class hep/dataforge/values/ValueType : java/lang/Enum { + public static final field BOOLEAN Lhep/dataforge/values/ValueType; + public static final field Companion Lhep/dataforge/values/ValueType$Companion; + public static final field NULL Lhep/dataforge/values/ValueType; + public static final field NUMBER Lhep/dataforge/values/ValueType; + public static final field STRING Lhep/dataforge/values/ValueType; + public static fun valueOf (Ljava/lang/String;)Lhep/dataforge/values/ValueType; + public static fun values ()[Lhep/dataforge/values/ValueType; +} + +public final class hep/dataforge/values/ValueType$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lhep/dataforge/values/ValueType$$serializer; + public fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lhep/dataforge/values/ValueType; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Lhep/dataforge/values/ValueType;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class hep/dataforge/values/ValueType$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + diff --git a/dataforge-meta/build.gradle.kts b/dataforge-meta/build.gradle.kts index f19a39fc..980924a7 100644 --- a/dataforge-meta/build.gradle.kts +++ b/dataforge-meta/build.gradle.kts @@ -1,9 +1,12 @@ -import scientifik.useSerialization - plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") + id("ru.mipt.npm.native") } -useSerialization() +kscience { + useSerialization{ + json() + } +} description = "Meta definition and basic operations on meta" \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt index 0ac29d86..2674d0a8 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Config.kt @@ -4,25 +4,30 @@ import hep.dataforge.names.Name import hep.dataforge.names.NameToken import hep.dataforge.names.asName import hep.dataforge.names.plus -import kotlinx.serialization.* +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlin.collections.set //TODO add validator to configuration -data class MetaListener( +public data class MetaListener( val owner: Any? = null, val action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit ) -interface ObservableMeta : Meta { - fun onChange(owner: Any?, action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit) - fun removeListener(owner: Any?) +public interface ObservableMeta : Meta { + public fun onChange(owner: Any?, action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit) + public fun removeListener(owner: Any?) } /** * Mutable meta representing object state */ -@Serializable -class Config : AbstractMutableMeta<Config>(), ObservableMeta { +@Serializable(Config.Companion::class) +public class Config() : AbstractMutableMeta<Config>(), ObservableMeta { private val listeners = HashSet<MetaListener>() @@ -46,12 +51,12 @@ class Config : AbstractMutableMeta<Config>(), ObservableMeta { override fun replaceItem(key: NameToken, oldItem: MetaItem<Config>?, newItem: MetaItem<Config>?) { if (newItem == null) { - _items.remove(key) + children.remove(key) if (oldItem != null && oldItem is MetaItem.NodeItem<Config>) { oldItem.node.removeListener(this) } } else { - _items[key] = newItem + children[key] = newItem if (newItem is MetaItem.NodeItem) { newItem.node.onChange(this) { name, oldChild, newChild -> itemChanged(key + name, oldChild, newChild) @@ -68,10 +73,9 @@ class Config : AbstractMutableMeta<Config>(), ObservableMeta { override fun empty(): Config = Config() - @Serializer(Config::class) - companion object ConfigSerializer : KSerializer<Config> { + public companion object ConfigSerializer : KSerializer<Config> { - fun empty(): Config = Config() + public fun empty(): Config = Config() override val descriptor: SerialDescriptor get() = MetaSerializer.descriptor override fun deserialize(decoder: Decoder): Config { @@ -84,9 +88,9 @@ class Config : AbstractMutableMeta<Config>(), ObservableMeta { } } -operator fun Config.get(token: NameToken): MetaItem<Config>? = items[token] +public operator fun Config.get(token: NameToken): MetaItem<Config>? = items[token] -fun Meta.asConfig(): Config = this as? Config ?: Config().also { builder -> +public fun Meta.asConfig(): Config = this as? Config ?: Config().also { builder -> this.items.mapValues { entry -> val item = entry.value builder[entry.key.asName()] = when (item) { diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt index 794292b9..764ee1ea 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Configurable.kt @@ -1,115 +1,24 @@ package hep.dataforge.meta -import hep.dataforge.meta.descriptors.* import hep.dataforge.names.Name -import hep.dataforge.names.asName -import hep.dataforge.names.toName -import hep.dataforge.values.Value import kotlin.properties.ReadWriteProperty -import kotlin.reflect.KProperty /** - * A container that holds a [Config] and a default item provider. - * Default item provider could be use for example to reference parent configuration. - * It is not possible to know if some property is declared by provider just by looking on [Configurable], - * this information should be provided externally. + * A container that holds a [Config]. */ -interface Configurable : Described, MutableItemProvider { +public interface Configurable { /** * Backing config */ - val config: Config - - /** - * Default meta item provider - */ - fun getDefaultItem(name: Name): MetaItem<*>? = null - - /** - * Check if property with given [name] could be assigned to [value] - */ - fun validateItem(name: Name, item: MetaItem<*>?): Boolean { - val descriptor = descriptor?.get(name) - return descriptor?.validateItem(item) ?: true - } - - override val descriptor: NodeDescriptor? get() = null - - /** - * Get a property with default - */ - override fun getItem(name: Name): MetaItem<*>? = - config[name] ?: getDefaultItem(name) ?: descriptor?.get(name)?.defaultItem() - - /** - * Set a configurable property - */ - override fun setItem(name: Name, item: MetaItem<*>?) { - if (validateItem(name, item)) { - config.setItem(name, item) - } else { - error("Validation failed for property $name with value $item") - } - } + public val config: Config } -/** - * Reset the property to its default value - */ -fun Configurable.resetProperty(name: Name) { - setItem(name, null) -} -fun Configurable.getItem(key: String) = getItem(key.toName()) - -fun Configurable.setItem(name: Name, value: Value?) = setItem(name, value?.let { MetaItem.ValueItem(value) }) -fun Configurable.setItem(name: Name, meta: Meta?) = setItem(name, meta?.let { MetaItem.NodeItem(meta) }) - -fun Configurable.setItem(key: String, item: MetaItem<*>?) = setItem(key.toName(), item) - -fun Configurable.setItem(key: String, value: Value?) = setItem(key, value?.let { MetaItem.ValueItem(value) }) -fun Configurable.setItem(key: String, meta: Meta?) = setItem(key, meta?.let { MetaItem.NodeItem(meta) }) - -fun <T : Configurable> T.configure(meta: Meta): T = this.apply { config.update(meta) } +public fun <T : Configurable> T.configure(meta: Meta): T = this.apply { config.update(meta) } @DFBuilder -inline fun <T : Configurable> T.configure(action: Config.() -> Unit): T = apply { config.apply(action) } +public inline fun <T : Configurable> T.configure(action: Config.() -> Unit): T = apply { config.apply(action) } /* Node delegates */ -fun Configurable.config(key: Name? = null): ReadWriteProperty<Any?, Config?> = - config.node(key) - -fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty<Any?, Meta?> = item(key).convert( - reader = { it.node }, - writer = { it?.let { MetaItem.NodeItem(it) } } -) - -fun <T : Configurable> Configurable.spec( - spec: Specification<T>, key: Name? = null -): ReadWriteProperty<Any?, T?> = object : ReadWriteProperty<Any?, T?> { - override fun getValue(thisRef: Any?, property: KProperty<*>): T? { - val name = key ?: property.name.asName() - return config[name].node?.let { spec.wrap(it) } - } - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { - val name = key ?: property.name.asName() - config[name] = value?.config - } -} - -fun <T : Configurable> Configurable.spec( - spec: Specification<T>, default: T, key: Name? = null -): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> { - override fun getValue(thisRef: Any?, property: KProperty<*>): T { - val name = key ?: property.name.asName() - return config[name].node?.let { spec.wrap(it) } ?: default - } - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { - val name = key ?: property.name.asName() - config[name] = value.config - } -} - +public fun Configurable.config(key: Name? = null): ReadWriteProperty<Any?, Config?> = config.node(key) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt index aa2dec23..eab2573f 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/ItemDelegate.kt @@ -5,62 +5,107 @@ import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.values.Value import kotlin.properties.ReadOnlyProperty -import kotlin.reflect.KProperty /* Meta delegates */ -open class ItemDelegate( - open val owner: ItemProvider, - val key: Name? = null, - open val default: MetaItem<*>? = null -) : ReadOnlyProperty<Any?, MetaItem<*>?> { - override fun getValue(thisRef: Any?, property: KProperty<*>): MetaItem<*>? { - return owner.getItem(key ?: property.name.asName()) ?: default - } -} +public typealias ItemDelegate = ReadOnlyProperty<Any?, MetaItem<*>?> -fun ItemProvider.item(key: Name? = null): ItemDelegate = ItemDelegate(this, key) +public fun ItemProvider.item(key: Name? = null): ItemDelegate = ReadOnlyProperty { _, property -> + getItem(key ?: property.name.asName()) +} //TODO add caching for sealed nodes -//Read-only delegates for Metas +/** + * Apply a converter to this delegate creating a delegate with a custom type + */ +public fun <R : Any> ItemDelegate.convert( + converter: MetaConverter<R>, +): ReadOnlyProperty<Any?, R?> = ReadOnlyProperty { thisRef, property -> + this@convert.getValue(thisRef, property)?.let(converter::itemToObject) +} + +/* + * + */ +public fun <R : Any> ItemDelegate.convert( + converter: MetaConverter<R>, + default: () -> R, +): ReadOnlyProperty<Any?, R> = ReadOnlyProperty<Any?, R> { thisRef, property -> + this@convert.getValue(thisRef, property)?.let(converter::itemToObject) ?: default() +} + +/** + * A converter with a custom reader transformation + */ +public fun <R> ItemDelegate.convert( + reader: (MetaItem<*>?) -> R, +): ReadOnlyProperty<Any?, R> = ReadOnlyProperty<Any?, R> { thisRef, property -> + this@convert.getValue(thisRef, property).let(reader) +} + +/* Read-only delegates for [ItemProvider] */ /** * A property delegate that uses custom key */ -fun ItemProvider.value(key: Name? = null): ReadOnlyProperty<Any?, Value?> = +public fun ItemProvider.value(key: Name? = null): ReadOnlyProperty<Any?, Value?> = item(key).convert(MetaConverter.value) -fun ItemProvider.string(key: Name? = null): ReadOnlyProperty<Any?, String?> = +public fun ItemProvider.string(key: Name? = null): ReadOnlyProperty<Any?, String?> = item(key).convert(MetaConverter.string) -fun ItemProvider.boolean(key: Name? = null): ReadOnlyProperty<Any?, Boolean?> = +public fun ItemProvider.boolean(key: Name? = null): ReadOnlyProperty<Any?, Boolean?> = item(key).convert(MetaConverter.boolean) -fun ItemProvider.number(key: Name? = null): ReadOnlyProperty<Any?, Number?> = +public fun ItemProvider.number(key: Name? = null): ReadOnlyProperty<Any?, Number?> = item(key).convert(MetaConverter.number) -fun ItemProvider.node(key: Name? = null): ReadOnlyProperty<Any?, Meta?> = +public fun ItemProvider.double(key: Name? = null): ReadOnlyProperty<Any?, Double?> = + item(key).convert(MetaConverter.double) + +public fun ItemProvider.float(key: Name? = null): ReadOnlyProperty<Any?, Float?> = + item(key).convert(MetaConverter.float) + +public fun ItemProvider.int(key: Name? = null): ReadOnlyProperty<Any?, Int?> = + item(key).convert(MetaConverter.int) + +public fun ItemProvider.long(key: Name? = null): ReadOnlyProperty<Any?, Long?> = + item(key).convert(MetaConverter.long) + +public fun ItemProvider.node(key: Name? = null): ReadOnlyProperty<Any?, Meta?> = item(key).convert(MetaConverter.meta) -fun ItemProvider.string(default: String, key: Name? = null): ReadOnlyProperty<Any?, String> = +public fun ItemProvider.string(default: String, key: Name? = null): ReadOnlyProperty<Any?, String> = item(key).convert(MetaConverter.string) { default } -fun ItemProvider.boolean(default: Boolean, key: Name? = null): ReadOnlyProperty<Any?, Boolean> = +public fun ItemProvider.boolean(default: Boolean, key: Name? = null): ReadOnlyProperty<Any?, Boolean> = item(key).convert(MetaConverter.boolean) { default } -fun ItemProvider.number(default: Number, key: Name? = null): ReadOnlyProperty<Any?, Number> = +public fun ItemProvider.number(default: Number, key: Name? = null): ReadOnlyProperty<Any?, Number> = item(key).convert(MetaConverter.number) { default } -inline fun <reified E : Enum<E>> ItemProvider.enum(default: E, key: Name? = null): ReadOnlyProperty<Any?, E> = +public fun ItemProvider.double(default: Double, key: Name? = null): ReadOnlyProperty<Any?, Double> = + item(key).convert(MetaConverter.double) { default } + +public fun ItemProvider.float(default: Float, key: Name? = null): ReadOnlyProperty<Any?, Float> = + item(key).convert(MetaConverter.float) { default } + +public fun ItemProvider.int(default: Int, key: Name? = null): ReadOnlyProperty<Any?, Int> = + item(key).convert(MetaConverter.int) { default } + +public fun ItemProvider.long(default: Long, key: Name? = null): ReadOnlyProperty<Any?, Long> = + item(key).convert(MetaConverter.long) { default } + +public inline fun <reified E : Enum<E>> ItemProvider.enum(default: E, key: Name? = null): ReadOnlyProperty<Any?, E> = item(key).convert(MetaConverter.enum()) { default } -fun ItemProvider.string(key: Name? = null, default: () -> String): ReadOnlyProperty<Any?, String> = +public fun ItemProvider.string(key: Name? = null, default: () -> String): ReadOnlyProperty<Any?, String> = item(key).convert(MetaConverter.string, default) -fun ItemProvider.boolean(key: Name? = null, default: () -> Boolean): ReadOnlyProperty<Any?, Boolean> = +public fun ItemProvider.boolean(key: Name? = null, default: () -> Boolean): ReadOnlyProperty<Any?, Boolean> = item(key).convert(MetaConverter.boolean, default) -fun ItemProvider.number(key: Name? = null, default: () -> Number): ReadOnlyProperty<Any?, Number> = +public fun ItemProvider.number(key: Name? = null, default: () -> Number): ReadOnlyProperty<Any?, Number> = item(key).convert(MetaConverter.number, default) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/JsonMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/JsonMeta.kt index 221b040d..2cabc8f1 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/JsonMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/JsonMeta.kt @@ -4,6 +4,7 @@ package hep.dataforge.meta import hep.dataforge.meta.JsonMeta.Companion.JSON_ARRAY_KEY import hep.dataforge.meta.descriptors.ItemDescriptor +import hep.dataforge.meta.descriptors.ItemDescriptor.Companion.DEFAULT_INDEX_KEY import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.descriptors.ValueDescriptor import hep.dataforge.names.NameToken @@ -15,7 +16,7 @@ import kotlinx.serialization.json.* /** * @param descriptor reserved for custom serialization in future */ -fun Value.toJson(descriptor: ValueDescriptor? = null): JsonElement { +public fun Value.toJson(descriptor: ValueDescriptor? = null): JsonElement { return if (isList()) { JsonArray(list.map { it.toJson() }) } else { @@ -52,7 +53,7 @@ private fun Meta.toJsonWithIndex(descriptor: NodeDescriptor?, indexValue: String fun addElement(key: String) { val itemDescriptor = descriptor?.items?.get(key) val jsonKey = key.toJsonKey(itemDescriptor) - val items: Map<String, MetaItem<*>> = getIndexed(key) + val items: Map<String?, MetaItem<*>> = getIndexed(key) when (items.size) { 0 -> { //do nothing @@ -61,9 +62,9 @@ private fun Meta.toJsonWithIndex(descriptor: NodeDescriptor?, indexValue: String elementMap[jsonKey] = items.values.first().toJsonElement(itemDescriptor, null) } else -> { - val array = jsonArray { + val array = buildJsonArray { items.forEach { (index, item) -> - +item.toJsonElement(itemDescriptor, index) + add(item.toJsonElement(itemDescriptor, index)) } } elementMap[jsonKey] = array @@ -75,32 +76,31 @@ private fun Meta.toJsonWithIndex(descriptor: NodeDescriptor?, indexValue: String if (indexValue != null) { - val indexKey = descriptor?.indexKey ?: NodeDescriptor.DEFAULT_INDEX_KEY + val indexKey = descriptor?.indexKey ?: DEFAULT_INDEX_KEY elementMap[indexKey] = JsonPrimitive(indexValue) } return JsonObject(elementMap) } -fun Meta.toJson(descriptor: NodeDescriptor? = null): JsonObject = toJsonWithIndex(descriptor, null) +public fun Meta.toJson(descriptor: NodeDescriptor? = null): JsonObject = toJsonWithIndex(descriptor, null) -fun JsonObject.toMeta(descriptor: NodeDescriptor? = null): JsonMeta = JsonMeta(this, descriptor) +public fun JsonObject.toMeta(descriptor: NodeDescriptor? = null): JsonMeta = JsonMeta(this, descriptor) -fun JsonPrimitive.toValue(descriptor: ValueDescriptor?): Value { +public fun JsonPrimitive.toValue(descriptor: ValueDescriptor?): Value { return when (this) { JsonNull -> Null - is JsonLiteral -> { - when (body) { - true -> True - false -> False - is Number -> NumberValue(body as Number) - else -> StringValue(content) + else -> { + if (isString) { + StringValue(content) + } else { + content.parseValue() } } } } -fun JsonElement.toMetaItem(descriptor: ItemDescriptor? = null): MetaItem<JsonMeta> = when (this) { +public fun JsonElement.toMetaItem(descriptor: ItemDescriptor? = null): MetaItem<JsonMeta> = when (this) { is JsonPrimitive -> { val value = this.toValue(descriptor as? ValueDescriptor) MetaItem.ValueItem(value) @@ -122,7 +122,7 @@ fun JsonElement.toMetaItem(descriptor: ItemDescriptor? = null): MetaItem<JsonMet MetaItem.ValueItem(value) } else { //We can't return multiple items therefore we create top level node - json { JSON_ARRAY_KEY to this@toMetaItem }.toMetaItem(descriptor) + buildJsonObject { put(JSON_ARRAY_KEY, this@toMetaItem) }.toMetaItem(descriptor) } } } @@ -130,7 +130,7 @@ fun JsonElement.toMetaItem(descriptor: ItemDescriptor? = null): MetaItem<JsonMet /** * A meta wrapping json object */ -class JsonMeta(val json: JsonObject, val descriptor: NodeDescriptor? = null) : MetaBase() { +public class JsonMeta(private val json: JsonObject, private val descriptor: NodeDescriptor? = null) : MetaBase() { private fun buildItems(): Map<NameToken, MetaItem<JsonMeta>> { val map = LinkedHashMap<NameToken, MetaItem<JsonMeta>>() @@ -159,9 +159,9 @@ class JsonMeta(val json: JsonObject, val descriptor: NodeDescriptor? = null) : M ) map[key] = MetaItem.ValueItem(listValue) } else value.forEachIndexed { index, jsonElement -> - val indexKey = (itemDescriptor as? NodeDescriptor)?.indexKey ?: NodeDescriptor.DEFAULT_INDEX_KEY + val indexKey = (itemDescriptor as? NodeDescriptor)?.indexKey ?: DEFAULT_INDEX_KEY val indexValue: String = (jsonElement as? JsonObject) - ?.get(indexKey)?.contentOrNull + ?.get(indexKey)?.jsonPrimitive?.contentOrNull ?: index.toString() //In case index is non-string, the backward transformation will be broken. val token = key.withIndex(indexValue) @@ -174,10 +174,10 @@ class JsonMeta(val json: JsonObject, val descriptor: NodeDescriptor? = null) : M override val items: Map<NameToken, MetaItem<JsonMeta>> by lazy(::buildItems) - companion object{ + public companion object { /** * A key representing top-level json array of nodes, which could not be directly represented by a meta node */ - const val JSON_ARRAY_KEY = "@jsonArray" + public const val JSON_ARRAY_KEY: String = "@jsonArray" } } \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Laminate.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Laminate.kt index 7dec0790..5545358c 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Laminate.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Laminate.kt @@ -7,9 +7,9 @@ import hep.dataforge.names.NameToken * A meta laminate consisting of multiple immutable meta layers. For mutable front layer, use [Scheme]. * If [layers] list contains a [Laminate] it is flat-mapped. */ -class Laminate(layers: List<Meta>) : MetaBase() { +public class Laminate(layers: List<Meta>) : MetaBase() { - val layers: List<Meta> = layers.flatMap { + public val layers: List<Meta> = layers.flatMap { if (it is Laminate) { it.layers } else { @@ -17,8 +17,6 @@ class Laminate(layers: List<Meta>) : MetaBase() { } } - constructor(vararg layers: Meta?) : this(layers.filterNotNull()) - override val items: Map<NameToken, MetaItem<Meta>> by lazy { layers.map { it.items.keys }.flatten().associateWith { key -> layers.asSequence().map { it.items[key] }.filterNotNull().let(replaceRule) @@ -28,21 +26,21 @@ class Laminate(layers: List<Meta>) : MetaBase() { /** * Generate sealed meta using [mergeRule] */ - fun merge(): SealedMeta { + public fun merge(): SealedMeta { val items = layers.map { it.items.keys }.flatten().associateWith { key -> layers.asSequence().map { it.items[key] }.filterNotNull().merge() } return SealedMeta(items) } - companion object { + public companion object { /** * The default rule which always uses the first found item in sequence alongside with its children. * * TODO add picture */ - val replaceRule: (Sequence<MetaItem<*>>) -> MetaItem<SealedMeta> = { it.first().seal() } + public val replaceRule: (Sequence<MetaItem<*>>) -> MetaItem<SealedMeta> = { it.first().seal() } private fun Sequence<MetaItem<*>>.merge(): MetaItem<SealedMeta> { return when { @@ -76,14 +74,17 @@ class Laminate(layers: List<Meta>) : MetaBase() { * The values a replaced but meta children are joined * TODO add picture */ - val mergeRule: (Sequence<MetaItem<*>>) -> MetaItem<SealedMeta> = { it.merge() } + public val mergeRule: (Sequence<MetaItem<*>>) -> MetaItem<SealedMeta> = { it.merge() } } } +@Suppress("FunctionName") +public fun Laminate(vararg layers: Meta?): Laminate = Laminate(layers.filterNotNull()) + /** * Performance optimized version of get method */ -fun Laminate.getFirst(name: Name): MetaItem<*>? { +public fun Laminate.getFirst(name: Name): MetaItem<*>? { layers.forEach { layer -> layer[name]?.let { return it } } @@ -93,11 +94,11 @@ fun Laminate.getFirst(name: Name): MetaItem<*>? { /** * Create a new [Laminate] adding given layer to the top */ -fun Laminate.withTop(meta: Meta): Laminate = Laminate(listOf(meta) + layers) +public fun Laminate.withTop(meta: Meta): Laminate = Laminate(listOf(meta) + layers) /** * Create a new [Laminate] adding given layer to the bottom */ -fun Laminate.withBottom(meta: Meta): Laminate = Laminate(layers + meta) +public fun Laminate.withBottom(meta: Meta): Laminate = Laminate(layers + meta) //TODO add custom rules for Laminate merge diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt index a89d79c9..c8ed6755 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Meta.kt @@ -4,8 +4,12 @@ import hep.dataforge.meta.Meta.Companion.VALUE_KEY import hep.dataforge.meta.MetaItem.NodeItem import hep.dataforge.meta.MetaItem.ValueItem import hep.dataforge.names.* -import hep.dataforge.values.* -import kotlinx.serialization.* +import hep.dataforge.values.EnumValue +import hep.dataforge.values.Null +import hep.dataforge.values.Value +import hep.dataforge.values.boolean +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json /** @@ -13,28 +17,17 @@ import kotlinx.serialization.* * * a [ValueItem] (leaf) * * a [NodeItem] (node) */ -@Serializable -sealed class MetaItem<out M : Meta> { +@Serializable(MetaItemSerializer::class) +public sealed class MetaItem<out M : Meta>() { abstract override fun equals(other: Any?): Boolean abstract override fun hashCode(): Int - @Serializable - class ValueItem(val value: Value) : MetaItem<Nothing>() { + @Serializable(MetaItemSerializer::class) + public class ValueItem(public val value: Value) : MetaItem<Nothing>() { 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) - } - } - override fun equals(other: Any?): Boolean { return this.value == (other as? ValueItem)?.value } @@ -44,29 +37,18 @@ sealed class MetaItem<out M : Meta> { } } - @Serializable - class NodeItem<M : Meta>(@Serializable(MetaSerializer::class) val node: M) : MetaItem<M>() { + @Serializable(MetaItemSerializer::class) + public class NodeItem<M : Meta>(public val node: M) : MetaItem<M>() { //Fixing serializer for node could cause class cast problems, but it should not since Meta descendants are not serializeable override fun toString(): String = node.toString() - @Serializer(NodeItem::class) - companion object : KSerializer<NodeItem<out Meta>> { - override val descriptor: SerialDescriptor get() = MetaSerializer.descriptor - - override fun deserialize(decoder: Decoder): NodeItem<*> = NodeItem(MetaSerializer.deserialize(decoder)) - - override fun serialize(encoder: Encoder, value: NodeItem<*>) { - MetaSerializer.serialize(encoder, value.node) - } - } - override fun equals(other: Any?): Boolean = node == (other as? NodeItem<*>)?.node override fun hashCode(): Int = node.hashCode() } - companion object { - fun of(arg: Any?): MetaItem<*> { + public companion object { + public fun of(arg: Any?): MetaItem<*> { return when (arg) { null -> ValueItem(Null) is MetaItem<*> -> arg @@ -77,16 +59,24 @@ sealed class MetaItem<out M : Meta> { } } +public fun Value.asMetaItem(): ValueItem = ValueItem(this) +public fun <M : Meta> M.asMetaItem(): NodeItem<M> = NodeItem(this) + /** * The object that could be represented as [Meta]. Meta provided by [toMeta] method should fully represent object state. * Meaning that two states with the same meta are equal. */ -interface MetaRepr { - fun toMeta(): Meta +@Serializable(MetaSerializer::class) +public interface MetaRepr { + public fun toMeta(): Meta } -interface ItemProvider{ - fun getItem(name: Name): MetaItem<*>? +public fun interface ItemProvider { + public fun getItem(name: Name): MetaItem<*>? + + public companion object { + public val EMPTY: ItemProvider = ItemProvider { null } + } } /** @@ -96,15 +86,15 @@ interface ItemProvider{ * * * Same name siblings are supported via elements with the same [Name] but different queries */ -interface Meta : MetaRepr, ItemProvider { +public interface Meta : MetaRepr, ItemProvider { /** * Top level items of meta tree */ - val items: Map<NameToken, MetaItem<*>> + public val items: Map<NameToken, MetaItem<*>> override fun getItem(name: Name): MetaItem<*>? { if (name.isEmpty()) return NodeItem(this) - return name.first()?.let { token -> + return name.firstOrNull()?.let { token -> val tail = name.cutFirst() when (tail.length) { 0 -> items[token] @@ -121,15 +111,15 @@ interface Meta : MetaRepr, ItemProvider { override fun toString(): String - companion object { - const val TYPE = "meta" + public companion object { + public const val TYPE: String = "meta" /** * A key for single value node */ - const val VALUE_KEY = "@value" + public const val VALUE_KEY: String = "@value" - val EMPTY: Meta = object: MetaBase() { + public val EMPTY: Meta = object : MetaBase() { override val items: Map<NameToken, MetaItem<*>> = emptyMap() } } @@ -142,19 +132,19 @@ interface Meta : MetaRepr, ItemProvider { * * If [name] is empty return current [Meta] as a [NodeItem] */ -operator fun Meta?.get(name: Name): MetaItem<*>? = this?.getItem(name) +public operator fun Meta?.get(name: Name): MetaItem<*>? = this?.getItem(name) -operator fun Meta?.get(token: NameToken): MetaItem<*>? = this?.items?.get(token) +public 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] */ -operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName()) +public operator fun Meta?.get(key: String): MetaItem<*>? = get(key.toName()) /** * Get a sequence of [Name]-[Value] pairs */ -fun Meta.values(): Sequence<Pair<Name, Value>> { +public fun Meta.values(): Sequence<Pair<Name, Value>> { return items.asSequence().flatMap { (key, item) -> when (item) { is ValueItem -> sequenceOf(key.asName() to item.value) @@ -166,7 +156,7 @@ fun Meta.values(): Sequence<Pair<Name, Value>> { /** * Get a sequence of all [Name]-[MetaItem] pairs for all items including nodes */ -fun Meta.sequence(): Sequence<Pair<Name, MetaItem<*>>> { +public fun Meta.sequence(): Sequence<Pair<Name, MetaItem<*>>> { return sequence { items.forEach { (key, item) -> yield(key.asName() to item) @@ -179,33 +169,33 @@ fun Meta.sequence(): Sequence<Pair<Name, MetaItem<*>>> { } } -operator fun Meta.iterator(): Iterator<Pair<Name, MetaItem<*>>> = sequence().iterator() +public operator fun Meta.iterator(): Iterator<Pair<Name, MetaItem<*>>> = sequence().iterator() /** * A meta node that ensures that all of its descendants has at least the same type */ -interface MetaNode<out M : MetaNode<M>> : Meta { +public interface MetaNode<out M : MetaNode<M>> : Meta { override val items: Map<NameToken, MetaItem<M>> } /** * The same as [Meta.get], but with specific node type */ -operator fun <M : MetaNode<M>> M?.get(name: Name): MetaItem<M>? = if( this == null) { +public operator fun <M : MetaNode<M>> M?.get(name: Name): MetaItem<M>? = if (this == null) { null } else { @Suppress("UNCHECKED_CAST", "ReplaceGetOrSet") (this as Meta).get(name) as MetaItem<M>? // Do not change } -operator fun <M : MetaNode<M>> M?.get(key: String): MetaItem<M>? = this[key.toName()] +public operator fun <M : MetaNode<M>> M?.get(key: String): MetaItem<M>? = this[key.toName()] -operator fun <M : MetaNode<M>> M?.get(key: NameToken): MetaItem<M>? = this[key.asName()] +public operator fun <M : MetaNode<M>> M?.get(key: NameToken): MetaItem<M>? = this[key.asName()] /** * Equals, hashcode and to string for any meta */ -abstract class MetaBase : Meta { +public abstract class MetaBase : Meta { override fun equals(other: Any?): Boolean = if (other is Meta) { this.items == other.items @@ -215,30 +205,33 @@ abstract class MetaBase : Meta { override fun hashCode(): Int = items.hashCode() - override fun toString(): String = JSON_PRETTY.stringify(MetaSerializer, this) + override fun toString(): String = Json { + prettyPrint = true + useArrayPolymorphism = true + }.encodeToString(MetaSerializer, this) } /** * Equals and hash code implementation for meta node */ -abstract class AbstractMetaNode<M : MetaNode<M>> : MetaNode<M>, MetaBase() +public abstract class AbstractMetaNode<M : MetaNode<M>> : MetaNode<M>, MetaBase() /** * The meta implementation which is guaranteed to be immutable. * * If the argument is possibly mutable node, it is copied on creation */ -class SealedMeta internal constructor( - override val items: Map<NameToken, MetaItem<SealedMeta>> +public class SealedMeta internal constructor( + override val items: Map<NameToken, MetaItem<SealedMeta>>, ) : AbstractMetaNode<SealedMeta>() /** * Generate sealed node from [this]. If it is already sealed return it as is */ -fun Meta.seal(): SealedMeta = this as? SealedMeta ?: SealedMeta(items.mapValues { entry -> entry.value.seal() }) +public fun Meta.seal(): SealedMeta = this as? SealedMeta ?: SealedMeta(items.mapValues { entry -> entry.value.seal() }) @Suppress("UNCHECKED_CAST") -fun MetaItem<*>.seal(): MetaItem<SealedMeta> = when (this) { +public fun MetaItem<*>.seal(): MetaItem<SealedMeta> = when (this) { is ValueItem -> this is NodeItem -> NodeItem(node.seal()) } @@ -246,32 +239,32 @@ fun MetaItem<*>.seal(): MetaItem<SealedMeta> = when (this) { /** * Unsafe methods to access values and nodes directly from [MetaItem] */ -val MetaItem<*>?.value: Value? +public val MetaItem<*>?.value: Value? get() = (this as? ValueItem)?.value ?: (this?.node?.get(VALUE_KEY) as? ValueItem)?.value -val MetaItem<*>?.string get() = value?.string -val MetaItem<*>?.boolean get() = value?.boolean -val MetaItem<*>?.number get() = value?.number -val MetaItem<*>?.double get() = number?.toDouble() -val MetaItem<*>?.float get() = number?.toFloat() -val MetaItem<*>?.int get() = number?.toInt() -val MetaItem<*>?.long get() = number?.toLong() -val MetaItem<*>?.short get() = number?.toShort() +public val MetaItem<*>?.string: String? get() = value?.string +public val MetaItem<*>?.boolean: Boolean? get() = value?.boolean +public val MetaItem<*>?.number: Number? get() = value?.number +public val MetaItem<*>?.double: Double? get() = number?.toDouble() +public val MetaItem<*>?.float: Float? get() = number?.toFloat() +public val MetaItem<*>?.int: Int? get() = number?.toInt() +public val MetaItem<*>?.long: Long? get() = number?.toLong() +public val MetaItem<*>?.short: Short? get() = number?.toShort() -inline fun <reified E : Enum<E>> MetaItem<*>?.enum(): E? = if (this is ValueItem && this.value is EnumValue<*>) { +public inline fun <reified E : Enum<E>> MetaItem<*>?.enum(): E? = if (this is ValueItem && this.value is EnumValue<*>) { this.value.value as E } else { string?.let { enumValueOf<E>(it) } } -val MetaItem<*>?.stringList get() = value?.list?.map { it.string } ?: emptyList() +public val MetaItem<*>.stringList: List<String>? get() = value?.list?.map { it.string } -val <M : Meta> MetaItem<M>?.node: M? +public val <M : Meta> MetaItem<M>?.node: M? get() = when (this) { null -> null is ValueItem -> null//error("Trying to interpret value meta item as node item") is NodeItem -> node } -fun Meta.isEmpty() = this === Meta.EMPTY || this.items.isEmpty() \ No newline at end of file +public fun Meta.isEmpty(): Boolean = this === Meta.EMPTY || this.items.isEmpty() \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt index da1bafad..cd041275 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaBuilder.kt @@ -11,113 +11,109 @@ import kotlin.jvm.JvmName * DSL builder for meta. Is not intended to store mutable state */ @DFBuilder -class MetaBuilder : AbstractMutableMeta<MetaBuilder>() { +public class MetaBuilder : AbstractMutableMeta<MetaBuilder>() { override fun wrapNode(meta: Meta): MetaBuilder = if (meta is MetaBuilder) meta else meta.builder() override fun empty(): MetaBuilder = MetaBuilder() - infix fun String.put(item: MetaItem<*>?) { + public infix fun String.put(item: MetaItem<*>?) { set(this, item) } - infix fun String.put(value: Value?) { + public infix fun String.put(value: Value?) { set(this, value) } - infix fun String.put(string: String?) { + public infix fun String.put(string: String?) { set(this, string?.asValue()) } - infix fun String.put(number: Number?) { + public infix fun String.put(number: Number?) { set(this, number?.asValue()) } - infix fun String.put(boolean: Boolean?) { + public infix fun String.put(boolean: Boolean?) { set(this, boolean?.asValue()) } - infix fun String.put(enum: Enum<*>) { + public infix fun String.put(enum: Enum<*>) { set(this, EnumValue(enum)) } @JvmName("putValues") - infix fun String.put(iterable: Iterable<Value>) { + public infix fun String.put(iterable: Iterable<Value>) { set(this, iterable.asValue()) } @JvmName("putNumbers") - infix fun String.put(iterable: Iterable<Number>) { + public infix fun String.put(iterable: Iterable<Number>) { set(this, iterable.map { it.asValue() }.asValue()) } @JvmName("putStrings") - infix fun String.put(iterable: Iterable<String>) { + public infix fun String.put(iterable: Iterable<String>) { set(this, iterable.map { it.asValue() }.asValue()) } - infix fun String.put(array: DoubleArray) { + public infix fun String.put(array: DoubleArray) { set(this, array.asValue()) } - infix fun String.putValue(any: Any?) { - set(this, Value.of(any)) - } - - infix fun String.put(meta: Meta?) { + public infix fun String.put(meta: Meta?) { this@MetaBuilder[this] = meta } - infix fun String.put(repr: MetaRepr?) { + public infix fun String.put(repr: MetaRepr?) { set(this, repr?.toMeta()) } @JvmName("putMetas") - infix fun String.put(value: Iterable<Meta>) { - this@MetaBuilder[this] = value.toList() + public infix fun String.put(value: Iterable<Meta>) { + set(this,value.toList()) } - infix fun String.put(metaBuilder: MetaBuilder.() -> Unit) { + public infix fun String.put(metaBuilder: MetaBuilder.() -> Unit) { this@MetaBuilder[this] = MetaBuilder().apply(metaBuilder) } - infix fun Name.put(value: Value?) { + public infix fun Name.put(value: Value?) { set(this, value) } - infix fun Name.put(string: String?) { + public infix fun Name.put(string: String?) { set(this, string?.asValue()) } - infix fun Name.put(number: Number?) { + public infix fun Name.put(number: Number?) { set(this, number?.asValue()) } - infix fun Name.put(boolean: Boolean?) { + public infix fun Name.put(boolean: Boolean?) { set(this, boolean?.asValue()) } - infix fun Name.put(enum: Enum<*>) { + public infix fun Name.put(enum: Enum<*>) { set(this, EnumValue(enum)) } @JvmName("putValues") - infix fun Name.put(iterable: Iterable<Value>) { + public infix fun Name.put(iterable: Iterable<Value>) { set(this, iterable.asValue()) } - infix fun Name.put(meta: Meta?) { + public infix fun Name.put(meta: Meta?) { this@MetaBuilder[this] = meta } - infix fun Name.put(repr: MetaRepr?) { + public infix fun Name.put(repr: MetaRepr?) { set(this, repr?.toMeta()) } @JvmName("putMetas") - infix fun Name.put(value: Iterable<Meta>) { - this@MetaBuilder[this] = value.toList() + public infix fun Name.put(value: Iterable<Meta>) { + set(this, value.toList()) } - infix fun Name.put(metaBuilder: MetaBuilder.() -> Unit) { + public infix fun Name.put(metaBuilder: MetaBuilder.() -> Unit) { this@MetaBuilder[this] = MetaBuilder().apply(metaBuilder) } } @@ -125,7 +121,7 @@ class MetaBuilder : AbstractMutableMeta<MetaBuilder>() { /** * For safety, builder always copies the initial meta even if it is builder itself */ -fun Meta.builder(): MetaBuilder { +public fun Meta.builder(): MetaBuilder { return MetaBuilder().also { builder -> items.mapValues { entry -> val item = entry.value @@ -140,16 +136,10 @@ fun Meta.builder(): MetaBuilder { /** * Create a deep copy of this meta and apply builder to it */ -fun Meta.edit(builder: MetaBuilder.() -> Unit): MetaBuilder = builder().apply(builder) - -/** - * Build a [MetaBuilder] using given transformation - */ -@Deprecated("To be replaced with fake constructor", ReplaceWith("Meta")) -fun buildMeta(builder: MetaBuilder.() -> Unit): MetaBuilder = MetaBuilder().apply(builder) +public fun Meta.edit(builder: MetaBuilder.() -> Unit): MetaBuilder = builder().apply(builder) /** * Build a [MetaBuilder] using given transformation */ @Suppress("FunctionName") -fun Meta(builder: MetaBuilder.() -> Unit): MetaBuilder = MetaBuilder().apply(builder) \ No newline at end of file +public fun Meta(builder: MetaBuilder.() -> Unit): MetaBuilder = MetaBuilder().apply(builder) \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaSerializer.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaSerializer.kt index 6f0db59e..b20adba8 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaSerializer.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaSerializer.kt @@ -1,28 +1,68 @@ package hep.dataforge.meta import hep.dataforge.names.NameToken -import kotlinx.serialization.* +import hep.dataforge.values.ValueSerializer +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.InternalSerializationApi +import kotlinx.serialization.KSerializer import kotlinx.serialization.builtins.MapSerializer -import kotlinx.serialization.json.JsonInput -import kotlinx.serialization.json.JsonObjectSerializer -import kotlinx.serialization.json.JsonOutput +import kotlinx.serialization.descriptors.* +import kotlinx.serialization.encoding.* +import kotlinx.serialization.json.JsonDecoder +import kotlinx.serialization.json.JsonEncoder +import kotlinx.serialization.json.JsonObject +@OptIn(ExperimentalSerializationApi::class) +public object MetaItemSerializer : KSerializer<MetaItem<*>> { + + @OptIn(InternalSerializationApi::class) + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.meta.MetaItem") { + element<Boolean>("isNode") + element("content", buildSerialDescriptor("MetaItem.content", PolymorphicKind.SEALED)) + } + + override fun deserialize(decoder: Decoder): MetaItem<*> { + decoder.decodeStructure(descriptor) { + //Force strict serialization order + require(decodeElementIndex(descriptor) == 0) { "Node flag must be first item serialized" } + val isNode = decodeBooleanElement(descriptor, 0) + require(decodeElementIndex(descriptor) == 1) { "Missing MetaItem content" } + val item = if (isNode) { + decodeSerializableElement(descriptor,1, MetaSerializer).asMetaItem() + } else { + decodeSerializableElement(descriptor,1,ValueSerializer).asMetaItem() + } + require(decodeElementIndex(descriptor) == CompositeDecoder.DECODE_DONE){"Serialized MetaItem contains additional fields"} + return item + } + } + + override fun serialize(encoder: Encoder, value: MetaItem<*>) { + encoder.encodeStructure(descriptor) { + encodeBooleanElement(descriptor, 0, value is MetaItem.NodeItem) + when (value) { + is MetaItem.ValueItem -> encodeSerializableElement(descriptor, 1, ValueSerializer, value.value) + is MetaItem.NodeItem -> encodeSerializableElement(descriptor, 1, MetaSerializer, value.node) + } + } + } +} /** * Serialized for meta */ -@Serializer(Meta::class) -object MetaSerializer : KSerializer<Meta> { - private val mapSerializer = MapSerializer( - NameToken.serializer(), - MetaItem.serializer(MetaSerializer) +public object MetaSerializer : KSerializer<Meta> { + + private val mapSerializer: KSerializer<Map<NameToken, MetaItem<Meta>>> = MapSerializer( + NameToken, + MetaItemSerializer//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() + return if (decoder is JsonDecoder) { + JsonObject.serializer().deserialize(decoder).toMeta() } else { object : MetaBase() { override val items: Map<NameToken, MetaItem<*>> = mapSerializer.deserialize(decoder) @@ -31,8 +71,8 @@ object MetaSerializer : KSerializer<Meta> { } override fun serialize(encoder: Encoder, value: Meta) { - if (encoder is JsonOutput) { - JsonObjectSerializer.serialize(encoder, value.toJson()) + if (encoder is JsonEncoder) { + JsonObject.serializer().serialize(encoder, value.toJson()) } else { mapSerializer.serialize(encoder, value.items) } diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaWithDefault.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaWithDefault.kt new file mode 100644 index 00000000..2a225121 --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MetaWithDefault.kt @@ -0,0 +1,18 @@ +package hep.dataforge.meta + +import hep.dataforge.names.Name +import hep.dataforge.names.NameToken + +/** + * Meta object with default provider for items not present in the initial meta. + */ +public class MetaWithDefault(public val meta: Meta, public val default: ItemProvider) : MetaBase() { + override val items: Map<NameToken, MetaItem<*>> + get() = meta.items + + override fun getItem(name: Name): MetaItem<*>? { + return meta[name] ?: default.getItem(name) + } +} + +public fun Meta.withDefault(default: ItemProvider): MetaWithDefault = MetaWithDefault(this, default) \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemDelegate.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemDelegate.kt index 3885b809..32a7c7d4 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemDelegate.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemDelegate.kt @@ -5,163 +5,189 @@ import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.values.DoubleArrayValue import hep.dataforge.values.Value -import hep.dataforge.values.stringList +import hep.dataforge.values.asValue +import hep.dataforge.values.doubleArray import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty /* Read-write delegates */ -open class MutableItemDelegate( - override val owner: MutableItemProvider, - key: Name? = null, - default: MetaItem<*>? = null -) : ItemDelegate(owner, key, default), ReadWriteProperty<Any?, MetaItem<*>?> { +public typealias MutableItemDelegate = ReadWriteProperty<Any?, MetaItem<*>?> + +public fun MutableItemProvider.item(key: Name? = null): MutableItemDelegate = object : MutableItemDelegate { + override fun getValue(thisRef: Any?, property: KProperty<*>): MetaItem<*>? { + return getItem(key ?: property.name.asName()) + } override fun setValue(thisRef: Any?, property: KProperty<*>, value: MetaItem<*>?) { val name = key ?: property.name.asName() - owner.setItem(name, value) + setItem(name, value) } } -fun MutableItemProvider.item(key: Name? = null): MutableItemDelegate = - MutableItemDelegate(this, key) +/* Mutable converters */ -//Read-write delegates +/** + * A type converter for a mutable [MetaItem] delegate + */ +public fun <R : Any> MutableItemDelegate.convert( + converter: MetaConverter<R>, +): ReadWriteProperty<Any?, R?> = object : ReadWriteProperty<Any?, R?> { + + override fun getValue(thisRef: Any?, property: KProperty<*>): R? = + this@convert.getValue(thisRef, property)?.let(converter::itemToObject) + + override fun setValue(thisRef: Any?, property: KProperty<*>, value: R?) { + val item = value?.let(converter::objectToMetaItem) + this@convert.setValue(thisRef, property, item) + } +} + +public fun <R : Any> MutableItemDelegate.convert( + converter: MetaConverter<R>, + default: () -> R, +): ReadWriteProperty<Any?, R> = object : ReadWriteProperty<Any?, R> { + + override fun getValue(thisRef: Any?, property: KProperty<*>): R = + this@convert.getValue(thisRef, property)?.let(converter::itemToObject) ?: default() + + override fun setValue(thisRef: Any?, property: KProperty<*>, value: R) { + val item = value.let(converter::objectToMetaItem) + this@convert.setValue(thisRef, property, item) + } +} + +public fun <R> MutableItemDelegate.convert( + reader: (MetaItem<*>?) -> R, + writer: (R) -> MetaItem<*>?, +): ReadWriteProperty<Any?, R> = object : ReadWriteProperty<Any?, R> { + + override fun getValue(thisRef: Any?, property: KProperty<*>): R = + this@convert.getValue(thisRef, property).let(reader) + + override fun setValue(thisRef: Any?, property: KProperty<*>, value: R) { + val item = value?.let(writer) + this@convert.setValue(thisRef, property, item) + } +} + + + +/* Read-write delegates for [MutableItemProvider] */ /** * A property delegate that uses custom key */ -fun MutableItemProvider.value(key: Name? = null): ReadWriteProperty<Any?, Value?> = +public fun MutableItemProvider.value(key: Name? = null): ReadWriteProperty<Any?, Value?> = item(key).convert(MetaConverter.value) -fun MutableItemProvider.string(key: Name? = null): ReadWriteProperty<Any?, String?> = +public fun MutableItemProvider.string(key: Name? = null): ReadWriteProperty<Any?, String?> = item(key).convert(MetaConverter.string) -fun MutableItemProvider.boolean(key: Name? = null): ReadWriteProperty<Any?, Boolean?> = +public fun MutableItemProvider.boolean(key: Name? = null): ReadWriteProperty<Any?, Boolean?> = item(key).convert(MetaConverter.boolean) -fun MutableItemProvider.number(key: Name? = null): ReadWriteProperty<Any?, Number?> = +public fun MutableItemProvider.number(key: Name? = null): ReadWriteProperty<Any?, Number?> = item(key).convert(MetaConverter.number) -fun MutableItemProvider.string(default: String, key: Name? = null): ReadWriteProperty<Any?, String> = +public fun MutableItemProvider.string(default: String, key: Name? = null): ReadWriteProperty<Any?, String> = item(key).convert(MetaConverter.string) { default } -fun MutableItemProvider.boolean(default: Boolean, key: Name? = null): ReadWriteProperty<Any?, Boolean> = +public fun MutableItemProvider.boolean(default: Boolean, key: Name? = null): ReadWriteProperty<Any?, Boolean> = item(key).convert(MetaConverter.boolean) { default } -fun MutableItemProvider.number(default: Number, key: Name? = null): ReadWriteProperty<Any?, Number> = +public fun MutableItemProvider.number(default: Number, key: Name? = null): ReadWriteProperty<Any?, Number> = item(key).convert(MetaConverter.number) { default } -fun MutableItemProvider.value(key: Name? = null, default: () -> Value): ReadWriteProperty<Any?, Value> = +public fun MutableItemProvider.value(key: Name? = null, default: () -> Value): ReadWriteProperty<Any?, Value> = item(key).convert(MetaConverter.value, default) -fun MutableItemProvider.string(key: Name? = null, default: () -> String): ReadWriteProperty<Any?, String> = +public fun MutableItemProvider.string(key: Name? = null, default: () -> String): ReadWriteProperty<Any?, String> = item(key).convert(MetaConverter.string, default) -fun MutableItemProvider.boolean(key: Name? = null, default: () -> Boolean): ReadWriteProperty<Any?, Boolean> = +public fun MutableItemProvider.boolean(key: Name? = null, default: () -> Boolean): ReadWriteProperty<Any?, Boolean> = item(key).convert(MetaConverter.boolean, default) -fun MutableItemProvider.number(key: Name? = null, default: () -> Number): ReadWriteProperty<Any?, Number> = +public fun MutableItemProvider.number(key: Name? = null, default: () -> Number): ReadWriteProperty<Any?, Number> = item(key).convert(MetaConverter.number, default) -inline fun <reified E : Enum<E>> MutableItemProvider.enum(default: E, key: Name? = null): ReadWriteProperty<Any?, E> = +public inline fun <reified E : Enum<E>> MutableItemProvider.enum( + default: E, + key: Name? = null, +): ReadWriteProperty<Any?, E> = item(key).convert(MetaConverter.enum()) { default } -inline fun <reified M : MutableMeta<M>> M.node(key: Name? = null): ReadWriteProperty<Any?, M?> = +public inline fun <reified M : MutableMeta<M>> M.node(key: Name? = null): ReadWriteProperty<Any?, M?> = item(key).convert(reader = { it?.let { it.node as M } }, writer = { it?.let { MetaItem.NodeItem(it) } }) +/* Number delegates */ -fun <T> MutableItemProvider.item( - default: T? = null, - key: Name? = null, - writer: (T) -> MetaItem<*>? = { MetaItem.of(it) }, - reader: (MetaItem<*>?) -> T -): ReadWriteProperty<Any?, T> = MutableItemDelegate( - this, - key, - default?.let { MetaItem.of(it) } -).convert(reader = reader, writer = writer) - -fun Configurable.value(key: Name? = null): ReadWriteProperty<Any?, Value?> = - item(key).convert(MetaConverter.value) - -fun <T> MutableItemProvider.value( - default: T? = null, - key: Name? = null, - writer: (T) -> Value? = { Value.of(it) }, - reader: (Value?) -> T -): ReadWriteProperty<Any?, T> = MutableItemDelegate( - this, - key, - default?.let { MetaItem.of(it) } -).convert( - reader = { reader(it.value) }, - writer = { value -> writer(value)?.let { MetaItem.ValueItem(it) } } -) - -/* Number delegates*/ - -fun MutableItemProvider.int(key: Name? = null): ReadWriteProperty<Any?, Int?> = +public fun MutableItemProvider.int(key: Name? = null): ReadWriteProperty<Any?, Int?> = item(key).convert(MetaConverter.int) -fun MutableItemProvider.double(key: Name? = null): ReadWriteProperty<Any?, Double?> = +public fun MutableItemProvider.double(key: Name? = null): ReadWriteProperty<Any?, Double?> = item(key).convert(MetaConverter.double) -fun MutableItemProvider.long(key: Name? = null): ReadWriteProperty<Any?, Long?> = +public fun MutableItemProvider.long(key: Name? = null): ReadWriteProperty<Any?, Long?> = item(key).convert(MetaConverter.long) -fun MutableItemProvider.float(key: Name? = null): ReadWriteProperty<Any?, Float?> = +public fun MutableItemProvider.float(key: Name? = null): ReadWriteProperty<Any?, Float?> = item(key).convert(MetaConverter.float) /* Safe number delegates*/ -fun MutableItemProvider.int(default: Int, key: Name? = null): ReadWriteProperty<Any?, Int> = +public fun MutableItemProvider.int(default: Int, key: Name? = null): ReadWriteProperty<Any?, Int> = item(key).convert(MetaConverter.int) { default } -fun MutableItemProvider.double(default: Double, key: Name? = null): ReadWriteProperty<Any?, Double> = +public fun MutableItemProvider.double(default: Double, key: Name? = null): ReadWriteProperty<Any?, Double> = item(key).convert(MetaConverter.double) { default } -fun MutableItemProvider.long(default: Long, key: Name? = null): ReadWriteProperty<Any?, Long> = +public fun MutableItemProvider.long(default: Long, key: Name? = null): ReadWriteProperty<Any?, Long> = item(key).convert(MetaConverter.long) { default } -fun MutableItemProvider.float(default: Float, key: Name? = null): ReadWriteProperty<Any?, Float> = +public fun MutableItemProvider.float(default: Float, key: Name? = null): ReadWriteProperty<Any?, Float> = item(key).convert(MetaConverter.float) { default } -/* - * Extra delegates for special cases - */ -fun MutableItemProvider.stringList(vararg strings: String, key: Name? = null): ReadWriteProperty<Any?, List<String>> = - item(listOf(*strings), key) { - it?.value?.stringList ?: emptyList() - } +/* Extra delegates for special cases */ -fun MutableItemProvider.stringListOrNull( - vararg strings: String, - key: Name? = null -): ReadWriteProperty<Any?, List<String>?> = - item(listOf(*strings), key) { - it?.value?.stringList - } +public fun MutableItemProvider.stringList( + vararg default: String, + key: Name? = null, +): ReadWriteProperty<Any?, List<String>> = item(key).convert( + reader = { it?.stringList ?: listOf(*default) }, + writer = { it.map { str -> str.asValue() }.asValue().asMetaItem() } +) -fun MutableItemProvider.numberList(vararg numbers: Number, key: Name? = null): ReadWriteProperty<Any?, List<Number>> = - item(listOf(*numbers), key) { item -> - item?.value?.list?.map { it.number } ?: emptyList() - } +public fun MutableItemProvider.stringList( + key: Name? = null, +): ReadWriteProperty<Any?, List<String>?> = item(key).convert( + reader = { it?.stringList }, + writer = { it?.map { str -> str.asValue() }?.asValue()?.asMetaItem() } +) -/** - * A special delegate for double arrays - */ -fun MutableItemProvider.doubleArray(vararg doubles: Double, key: Name? = null): ReadWriteProperty<Any?, DoubleArray> = - item(doubleArrayOf(*doubles), key) { - (it.value as? DoubleArrayValue)?.value - ?: it?.value?.list?.map { value -> value.number.toDouble() }?.toDoubleArray() - ?: doubleArrayOf() - } +public fun MutableItemProvider.numberList( + vararg default: Number, + key: Name? = null, +): ReadWriteProperty<Any?, List<Number>> = item(key).convert( + reader = { it?.value?.list?.map { value -> value.number } ?: listOf(*default) }, + writer = { it.map { num -> num.asValue() }.asValue().asMetaItem() } +) -fun <T> MutableItemProvider.listValue( +/* A special delegate for double arrays */ + + +public fun MutableItemProvider.doubleArray( + vararg default: Double, + key: Name? = null, +): ReadWriteProperty<Any?, DoubleArray> = item(key).convert( + reader = { it?.value?.doubleArray ?: doubleArrayOf(*default) }, + writer = { DoubleArrayValue(it).asMetaItem() } +) + +public fun <T> MutableItemProvider.listValue( key: Name? = null, writer: (T) -> Value = { Value.of(it) }, - reader: (Value) -> T + reader: (Value) -> T, ): ReadWriteProperty<Any?, List<T>?> = item(key).convert(MetaConverter.valueList(writer, reader)) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemProvider.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemProvider.kt new file mode 100644 index 00000000..6a43af6e --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableItemProvider.kt @@ -0,0 +1,88 @@ +package hep.dataforge.meta + +import hep.dataforge.names.* +import hep.dataforge.values.Value +import kotlin.properties.ReadWriteProperty + +public interface MutableItemProvider : ItemProvider { + public fun setItem(name: Name, item: MetaItem<*>?) +} + +public fun MutableItemProvider.getItem(key: String): MetaItem<*>? = getItem(key.toName()) + +public fun MutableItemProvider.setValue(name: Name, value: Value?): Unit = + setItem(name, value?.let { MetaItem.ValueItem(value) }) + +public fun MutableItemProvider.setNode(name: Name, meta: Meta?): Unit = + setItem(name, meta?.let { MetaItem.NodeItem(meta) }) + +public fun MutableItemProvider.setItem(key: String, item: MetaItem<*>?): Unit = setItem(key.toName(), item) + +public fun MutableItemProvider.setValue(key: String, value: Value?): Unit = + setItem(key, value?.let { MetaItem.ValueItem(value) }) + +public fun MutableItemProvider.setNode(key: String, meta: Meta?): Unit = + setItem(key, meta?.let { MetaItem.NodeItem(meta) }) + +public fun MutableItemProvider.node(key: Name? = null): ReadWriteProperty<Any?, Meta?> = item(key).convert( + reader = { it.node }, + writer = { it?.let { MetaItem.NodeItem(it) } } +) + +@Suppress("NOTHING_TO_INLINE") +public inline fun MutableItemProvider.remove(name: Name): Unit = setItem(name, null) + +@Suppress("NOTHING_TO_INLINE") +public inline fun MutableItemProvider.remove(name: String): Unit = remove(name.toName()) + + +/** + * Universal unsafe set method + */ +public operator fun MutableItemProvider.set(name: Name, value: Any?) { + when (value) { + null -> remove(name) + is MetaItem<*> -> setItem(name, value) + is Meta -> setNode(name, value) + is Configurable -> setNode(name, value.config) + else -> setValue(name, Value.of(value)) + } +} + +public operator fun MutableItemProvider.set(name: NameToken, value: Any?): Unit = + set(name.asName(), value) + +public operator fun MutableItemProvider.set(key: String, value: Any?): Unit = + set(key.toName(), value) + +public operator fun MutableItemProvider.set(key: String, index: String, value: Any?): Unit = + set(key.toName().withIndex(index), value) + + + +/* Same name siblings generation */ + +public fun MutableItemProvider.setIndexedItems( + name: Name, + items: Iterable<MetaItem<*>>, + indexFactory: (MetaItem<*>, index: Int) -> String = { _, index -> index.toString() } +) { + val tokens = name.tokens.toMutableList() + val last = tokens.last() + items.forEachIndexed { index, meta -> + val indexedToken = NameToken(last.body, last.index + indexFactory(meta, index)) + tokens[tokens.lastIndex] = indexedToken + setItem(Name(tokens), meta) + } +} + +public fun MutableItemProvider.setIndexed( + name: Name, + metas: Iterable<Meta>, + indexFactory: (Meta, index: Int) -> String = { _, index -> index.toString() } +) { + setIndexedItems(name, metas.map { MetaItem.NodeItem(it) }) { item, index -> indexFactory(item.node!!, index) } +} + +public operator fun MutableItemProvider.set(name: Name, metas: Iterable<Meta>): Unit = setIndexed(name, metas) +public operator fun MutableItemProvider.set(name: String, metas: Iterable<Meta>): Unit = setIndexed(name.toName(), metas) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt index 03245b00..7903ba87 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/MutableMeta.kt @@ -1,13 +1,8 @@ package hep.dataforge.meta import hep.dataforge.names.* -import hep.dataforge.values.Value -interface MutableItemProvider : ItemProvider { - fun setItem(name: Name, item: MetaItem<*>?) -} - -interface MutableMeta<out M : MutableMeta<M>> : MetaNode<M>, MutableItemProvider { +public interface MutableMeta<out M : MutableMeta<M>> : MetaNode<M>, MutableItemProvider { override val items: Map<NameToken, MetaItem<M>> // fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit) // fun removeListener(owner: Any? = null) @@ -18,19 +13,19 @@ interface MutableMeta<out M : MutableMeta<M>> : MetaNode<M>, MutableItemProvider * * Changes in Meta are not thread safe. */ -abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(), MutableMeta<M> { - protected val _items: MutableMap<NameToken, MetaItem<M>> = LinkedHashMap() +public abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(), MutableMeta<M> { + protected val children: MutableMap<NameToken, MetaItem<M>> = LinkedHashMap() override val items: Map<NameToken, MetaItem<M>> - get() = _items + get() = children //protected abstract fun itemChanged(name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) protected open fun replaceItem(key: NameToken, oldItem: MetaItem<M>?, newItem: MetaItem<M>?) { if (newItem == null) { - _items.remove(key) + children.remove(key) } else { - _items[key] = newItem + children[key] = newItem } //itemChanged(key.asName(), oldItem, newItem) } @@ -56,12 +51,12 @@ abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(), when (name.length) { 0 -> error("Can't setValue meta item for empty name") 1 -> { - val token = name.first()!! + val token = name.firstOrNull()!! @Suppress("UNCHECKED_CAST") val oldItem: MetaItem<M>? = get(name) as? MetaItem<M> replaceItem(token, oldItem, wrapItem(item)) } else -> { - val token = name.first()!! + val token = name.firstOrNull()!! //get existing or create new node. Query is ignored for new node if (items[token] == null) { replaceItem(token, null, MetaItem.NodeItem(empty())) @@ -72,52 +67,13 @@ abstract class AbstractMutableMeta<M : MutableMeta<M>> : AbstractMetaNode<M>(), } } - -@Suppress("NOTHING_TO_INLINE") -inline fun MutableMeta<*>.remove(name: Name) = setItem(name, null) - -@Suppress("NOTHING_TO_INLINE") -inline fun MutableMeta<*>.remove(name: String) = remove(name.toName()) - -operator fun MutableMeta<*>.set(name: Name, item: MetaItem<*>?) = setItem(name, item) - -fun MutableMeta<*>.setValue(name: Name, value: Value) = setItem(name, MetaItem.ValueItem(value)) - -fun MutableMeta<*>.setValue(name: String, value: Value) = set(name.toName(), value) - -fun MutableMeta<*>.setItem(name: String, item: MetaItem<*>?) = setItem(name.toName(), item) - -fun MutableMeta<*>.setNode(name: Name, node: Meta) = - setItem(name, MetaItem.NodeItem(node)) - -fun MutableMeta<*>.setNode(name: String, node: Meta) = setNode(name.toName(), node) - -/** - * Universal unsafe set method - */ -operator fun MutableMeta<*>.set(name: Name, value: Any?) { - when (value) { - null -> remove(name) - is MetaItem<*> -> setItem(name, value) - is Meta -> setNode(name, value) - is Configurable -> setNode(name, value.config) - else -> setValue(name, Value.of(value)) - } -} - -operator fun MutableMeta<*>.set(name: NameToken, value: Any?) = set(name.asName(), value) - -operator fun MutableMeta<*>.set(key: String, value: Any?) = set(key.toName(), value) - -operator fun MutableMeta<*>.set(key: String, index: String, value: Any?) = set(key.toName().withIndex(index), value) - /** * Update existing mutable node with another node. The rules are following: * * value replaces anything * * node updates node and replaces anything but node * * node list updates node list if number of nodes in the list is the same and replaces anything otherwise */ -fun <M : MutableMeta<M>> M.update(meta: Meta) { +public fun <M : MutableMeta<M>> M.update(meta: Meta) { meta.items.forEach { entry -> when (val value = entry.value) { is MetaItem.ValueItem -> setValue(entry.key.asName(), value.value) @@ -127,54 +83,27 @@ fun <M : MutableMeta<M>> M.update(meta: Meta) { } } -/* Same name siblings generation */ - -fun MutableMeta<*>.setIndexedItems( - name: Name, - items: Iterable<MetaItem<*>>, - indexFactory: (MetaItem<*>, index: Int) -> String = { _, index -> index.toString() } -) { - val tokens = name.tokens.toMutableList() - val last = tokens.last() - items.forEachIndexed { index, meta -> - val indexedToken = NameToken(last.body, last.index + indexFactory(meta, index)) - tokens[tokens.lastIndex] = indexedToken - setItem(Name(tokens), meta) - } -} - -fun MutableMeta<*>.setIndexed( - name: Name, - metas: Iterable<Meta>, - indexFactory: (Meta, index: Int) -> String = { _, index -> index.toString() } -) { - setIndexedItems(name, metas.map { MetaItem.NodeItem(it) }) { item, index -> indexFactory(item.node!!, index) } -} - -operator fun MutableMeta<*>.set(name: Name, metas: Iterable<Meta>): Unit = setIndexed(name, metas) -operator fun MutableMeta<*>.set(name: String, metas: Iterable<Meta>): Unit = setIndexed(name.toName(), metas) - /** * Append the node with a same-name-sibling, automatically generating numerical index */ -fun <M : MutableMeta<M>> M.append(name: Name, value: Any?) { +public fun <M : MutableMeta<M>> M.append(name: Name, value: Any?) { require(!name.isEmpty()) { "Name could not be empty for append operation" } - val newIndex = name.last()!!.index - if (newIndex.isNotEmpty()) { + val newIndex = name.lastOrNull()!!.index + if (newIndex != null) { set(name, value) } else { - val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1 + val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.maxOrNull() ?: -1) + 1 set(name.withIndex(index.toString()), value) } } -fun <M : MutableMeta<M>> M.append(name: String, value: Any?) = append(name.toName(), value) +public fun <M : MutableMeta<M>> M.append(name: String, value: Any?): Unit = append(name.toName(), value) /** * Apply existing node with given [builder] or create a new element with it. */ @DFExperimental -fun <M : AbstractMutableMeta<M>> M.edit(name: Name, builder: M.() -> Unit) { +public fun <M : AbstractMutableMeta<M>> M.edit(name: Name, builder: M.() -> Unit) { val item = when (val existingItem = get(name)) { null -> empty().also { set(name, it) } is MetaItem.NodeItem<M> -> existingItem.node diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt index deec949f..1fc74316 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Scheme.kt @@ -3,28 +3,54 @@ package hep.dataforge.meta import hep.dataforge.meta.descriptors.* import hep.dataforge.names.Name import hep.dataforge.names.NameToken -import hep.dataforge.names.plus +import hep.dataforge.names.asName /** * A base for delegate-based or descriptor-based scheme. [Scheme] has an empty constructor to simplify usage from [Specification]. + * Default item provider and [NodeDescriptor] are optional */ -open class Scheme() : Configurable, Described, MetaRepr { - constructor(config: Config, defaultProvider: (Name) -> MetaItem<*>?) : this() { - this.config = config - this.defaultProvider = defaultProvider +public open class Scheme( + config: Config = Config(), + internal var default: ItemProvider? = null, + descriptor: NodeDescriptor? = null, +) : Configurable, MutableItemProvider, Described, MetaRepr { + + override var config: Config = config + internal set(value) { + //Fix problem with `init` blocks in specifications + field = value.apply { update(field) } + } + + override var descriptor: NodeDescriptor? = descriptor + internal set + + + public fun getDefaultItem(name: Name): MetaItem<*>? { + return default?.getItem(name) ?: descriptor?.get(name)?.defaultItem() } - //constructor(config: Config, default: Meta) : this(config, { default[it] }) - constructor(config: Config) : this(config, { null }) + /** + * Get a property with default + */ + override fun getItem(name: Name): MetaItem<*>? = config[name] ?: getDefaultItem(name) - final override var config: Config = Config() - internal set + /** + * Check if property with given [name] could be assigned to [item] + */ + public fun validateItem(name: Name, item: MetaItem<*>?): Boolean { + val descriptor = descriptor?.get(name) + return descriptor?.validateItem(item) ?: true + } - var defaultProvider: (Name) -> MetaItem<*>? = { null } - internal set - - override fun getDefaultItem(name: Name): MetaItem<*>? { - return defaultProvider(name) ?: descriptor?.get(name)?.defaultItem() + /** + * Set a configurable property + */ + override fun setItem(name: Name, item: MetaItem<*>?) { + if (validateItem(name, item)) { + config.setItem(name, item) + } else { + error("Validation failed for property $name with value $item") + } } /** @@ -32,56 +58,73 @@ open class Scheme() : Configurable, Described, MetaRepr { * values if default value is unavailable. * Values from [defaultProvider] completely replace */ - open val defaultLayer: Meta get() = DefaultLayer(Name.EMPTY) + public open val defaultLayer: Meta + get() = object : MetaBase() { + override val items: Map<NameToken, MetaItem<*>> = buildMap { + descriptor?.items?.forEach { (key, itemDescriptor) -> + val token = NameToken(key) + val name = token.asName() + val item = default?.getItem(name) ?: itemDescriptor.defaultItem() + if (item != null) { + put(token, item) + } + } + } + } override fun toMeta(): Laminate = Laminate(config, defaultLayer) - private inner class DefaultLayer(val path: Name) : MetaBase() { - override val items: Map<NameToken, MetaItem<*>> = - (descriptor?.get(path) as? NodeDescriptor)?.items?.entries?.associate { (key, descriptor) -> - val token = NameToken(key) - val fullName = path + token - val item: MetaItem<*> = when (descriptor) { - is ValueDescriptor -> getDefaultItem(fullName) ?: descriptor.defaultItem() - is NodeDescriptor -> MetaItem.NodeItem(DefaultLayer(fullName)) - } - token to item - } ?: emptyMap() - } + public fun isEmpty(): Boolean = config.isEmpty() } -inline operator fun <T : Scheme> T.invoke(block: T.() -> Unit) = apply(block) +/** + * A shortcut to edit a [Scheme] object in-place + */ +public inline operator fun <T : Scheme> T.invoke(block: T.() -> Unit): T = apply(block) /** * A specification for simplified generation of wrappers */ -open class SchemeSpec<T : Scheme>(val builder: () -> T) : - Specification<T> { - override fun empty(): T = builder() +public open class SchemeSpec<T : Scheme>( + private val builder: (config: Config, defaultProvider: ItemProvider, descriptor: NodeDescriptor?) -> T, +) : Specification<T>, Described { - override fun wrap(config: Config, defaultProvider: (Name) -> MetaItem<*>?): T { - return empty().apply { + public constructor(emptyBuilder: () -> T) : this({ config: Config, defaultProvider: ItemProvider, descriptor: NodeDescriptor? -> + emptyBuilder().apply { this.config = config - this.defaultProvider = defaultProvider + this.default = defaultProvider + this.descriptor = descriptor } + }) + + override fun read(meta: Meta, defaultProvider: ItemProvider): T = + builder(Config(), meta.withDefault(defaultProvider), descriptor) + + override fun wrap(config: Config, defaultProvider: ItemProvider): T { + return builder(config, defaultProvider, descriptor) } + //TODO Generate descriptor from Scheme class + override val descriptor: NodeDescriptor? get() = null + @Suppress("OVERRIDE_BY_INLINE") - final override inline operator fun invoke(action: T.() -> Unit) = empty().apply(action) + final override inline operator fun invoke(action: T.() -> Unit): T = empty().apply(action) } -/** - * A scheme that uses [Meta] as a default layer - */ -open class MetaScheme( - val meta: Meta, - override val descriptor: NodeDescriptor? = null, - config: Config = Config() -) : Scheme(config, meta::get) { - override val defaultLayer: Meta get() = Laminate(meta, descriptor?.defaultItem().node) +///** +// * A scheme that uses [Meta] as a default layer +// */ +//public open class MetaScheme( +// private val meta: Meta, +// override val descriptor: NodeDescriptor? = null, +// config: Config = Config(), +//) : Scheme(config, meta) { +// override val defaultLayer: Meta get() = Laminate(meta, descriptor?.defaultItem().node) +//} + +public fun Meta.asScheme(): Scheme = Scheme().apply { + config = this@asScheme.asConfig() } -fun Meta.asScheme() = - MetaScheme(this) - -fun <T : Configurable> Meta.toScheme(spec: Specification<T>, block: T.() -> Unit) = spec.wrap(this).apply(block) \ No newline at end of file +public fun <T : MutableItemProvider> Meta.toScheme(spec: Specification<T>, block: T.() -> Unit = {}): T = + spec.read(this).apply(block) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt index 85cf7b96..05c31dc3 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/Specification.kt @@ -1,67 +1,102 @@ package hep.dataforge.meta import hep.dataforge.names.Name +import hep.dataforge.names.asName import kotlin.jvm.JvmName +import kotlin.properties.ReadWriteProperty +import kotlin.reflect.KProperty /** * Allows to apply custom configuration in a type safe way to simple untyped configuration. * By convention [Scheme] companion should inherit this class * */ -interface Specification<T : Configurable> { - fun empty() = wrap() +public interface Specification<T : MutableItemProvider> { + /** + * Read generic read-only meta with this [Specification] producing instance of desired type. + */ + public fun read(meta: Meta, defaultProvider: ItemProvider = ItemProvider.EMPTY): T /** - * Wrap generic configuration producing instance of desired type + * Wrap mutable [Config], using it as inner storage (changes to [Specification] are reflected on [Config] */ - fun wrap(config: Config = Config(), defaultProvider: (Name) -> MetaItem<*>? = { null }): T + public fun wrap(config: Config, defaultProvider: ItemProvider = ItemProvider.EMPTY): T = + read(config as Meta, defaultProvider) - operator fun invoke(action: T.() -> Unit): T = empty().apply(action) + /** + * Generate an empty object + */ + public fun empty(): T = read(Meta.EMPTY) + + /** + * A convenience method to use specifications in builders + */ + public operator fun invoke(action: T.() -> Unit): T = empty().apply(action) } /** * Update given configuration using given type as a builder */ -fun <T : Configurable> Specification<T>.update(config: Config, action: T.() -> Unit): T = wrap(config).apply(action) - -/** - * Wrap a configuration using static meta as default - */ -fun <T : Configurable> Specification<T>.wrap(config: Config = Config(), default: Meta = Meta.EMPTY): T = - wrap(config) { default[it] } - -/** - * Wrap a configuration using static meta as default - */ -fun <T : Configurable> Specification<T>.wrap(source: Meta): T { - val default = source.seal() - return wrap(source.asConfig(), default) -} +public fun <T : MutableItemProvider> Specification<T>.update(meta: Meta, action: T.() -> Unit): T = + read(meta).apply(action) /** * Apply specified configuration to configurable */ -fun <T : Configurable, C : Configurable, S : Specification<C>> T.configure(spec: S, action: C.() -> Unit) = - apply { spec.update(config, action) } +public fun <T : MetaRepr, C : MutableItemProvider, S : Specification<C>> T.configure(spec: S, action: C.() -> Unit): T = + apply { spec.update(toMeta(), action) } /** * Update configuration using given specification */ -fun <C : Configurable, S : Specification<C>> Configurable.update(spec: S, action: C.() -> Unit) = +public fun <C : MutableItemProvider, S : Specification<C>> Configurable.update( + spec: S, + action: C.() -> Unit, +): Configurable = apply { spec.update(config, action) } /** * Create a style based on given specification */ -fun <C : Configurable, S : Specification<C>> S.createStyle(action: C.() -> Unit): Meta = +public fun <C : MutableItemProvider, S : Specification<C>> S.createStyle(action: C.() -> Unit): Meta = Config().also { update(it, action) } -fun <T : Configurable> MetaItem<*>.spec(spec: Specification<T>): T? = node?.let { +public fun <T : MutableItemProvider> MetaItem<*>.spec(spec: Specification<T>): T? = node?.let { spec.wrap( Config(), it ) } @JvmName("configSpec") -fun <T : Configurable> MetaItem<Config>.spec(spec: Specification<T>): T? = node?.let { spec.wrap(it) } +public fun <T : MutableItemProvider> MetaItem<Config>.spec(spec: Specification<T>): T? = node?.let { spec.wrap(it) } + +public fun <T : Scheme> MutableItemProvider.spec( + spec: Specification<T>, key: Name? = null, +): ReadWriteProperty<Any?, T?> = object : ReadWriteProperty<Any?, T?> { + override fun getValue(thisRef: Any?, property: KProperty<*>): T? { + val name = key ?: property.name.asName() + return getItem(name).node?.let { spec.read(it) } + } + + override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { + val name = key ?: property.name.asName() + setItem(name, value?.toMeta()?.asMetaItem()) + } +} + +public fun <T : Scheme> MutableItemProvider.spec( + spec: Specification<T>, + default: T, + key: Name? = null, +): ReadWriteProperty<Any?, T> = object : ReadWriteProperty<Any?, T> { + override fun getValue(thisRef: Any?, property: KProperty<*>): T { + val name = key ?: property.name.asName() + return getItem(name).node?.let { spec.read(it) } ?: default + } + + override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { + val name = key ?: property.name.asName() + setItem(name, value.toMeta().asMetaItem()) + } +} \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/annotations.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/annotations.kt index 2085bc5d..69ffa8aa 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/annotations.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/annotations.kt @@ -4,8 +4,8 @@ package hep.dataforge.meta * General marker for dataforge builders */ @DslMarker -annotation class DFBuilder +public annotation class DFBuilder @RequiresOptIn(level = RequiresOptIn.Level.WARNING) @Retention(AnnotationRetention.BINARY) -annotation class DFExperimental \ No newline at end of file +public annotation class DFExperimental \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/Described.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/Described.kt index ac8ba74a..4af17dfb 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/Described.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/Described.kt @@ -3,11 +3,11 @@ package hep.dataforge.meta.descriptors /** * An object which provides its descriptor */ -interface Described { - val descriptor: ItemDescriptor? +public interface Described { + public val descriptor: ItemDescriptor? - companion object { - const val DESCRIPTOR_NODE = "@descriptor" + public companion object { + //public const val DESCRIPTOR_NODE: String = "@descriptor" } } diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/DescriptorMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/DescriptorMeta.kt index 47c90370..9a5b915d 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/DescriptorMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/DescriptorMeta.kt @@ -1,32 +1,48 @@ package hep.dataforge.meta.descriptors import hep.dataforge.meta.Laminate +import hep.dataforge.meta.Meta import hep.dataforge.meta.MetaBase import hep.dataforge.meta.MetaItem import hep.dataforge.names.NameToken -import hep.dataforge.values.Null /** - * A [Meta] that wraps a descriptor node + * A [Meta] that is constructed from [NodeDescriptor] */ -class DescriptorMeta(val descriptor: NodeDescriptor) : MetaBase() { +private class DescriptorMeta(val descriptor: NodeDescriptor) : Meta, MetaBase() { override val items: Map<NameToken, MetaItem<*>> - get() = descriptor.items.entries.associate { entry -> - NameToken(entry.key) to entry.value.defaultItem() + get() = buildMap { + descriptor.items.forEach { (token, descriptorItem) -> + val item = descriptorItem.defaultItem() + if (item != null) { + put(NameToken(token), item) + } + } } } -fun NodeDescriptor.buildDefaultMeta() = Laminate(default, DescriptorMeta(this)) +/** + * Generate a laminate representing default item set generated by this descriptor + */ +public fun NodeDescriptor.defaultMeta(): Laminate = Laminate(default, DescriptorMeta(this)) -fun NodeDescriptor.defaultItem(): MetaItem.NodeItem<*> = - MetaItem.NodeItem(buildDefaultMeta()) +/** + * Build a default [MetaItem.NodeItem] from this node descriptor + */ +internal fun NodeDescriptor.defaultItem(): MetaItem.NodeItem<*> = + MetaItem.NodeItem(defaultMeta()) -fun ValueDescriptor.defaultItem(): MetaItem.ValueItem = MetaItem.ValueItem(default ?: Null) +/** + * Build a default [MetaItem.ValueItem] from this descriptor + */ +internal fun ValueDescriptor.defaultItem(): MetaItem.ValueItem? { + return MetaItem.ValueItem(default ?: return null) +} /** * Build a default [MetaItem] from descriptor. */ -fun ItemDescriptor.defaultItem(): MetaItem<*> { +public fun ItemDescriptor.defaultItem(): MetaItem<*>? { return when (this) { is ValueDescriptor -> defaultItem() is NodeDescriptor -> defaultItem() diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/ItemDescriptor.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/ItemDescriptor.kt index a277e18d..cbb56fa1 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/ItemDescriptor.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/descriptors/ItemDescriptor.kt @@ -4,29 +4,26 @@ import hep.dataforge.meta.* import hep.dataforge.names.* import hep.dataforge.values.* +/** + * A common parent for [ValueDescriptor] and [NodeDescriptor]. Describes a single [MetaItem] or a group of same-name-siblings. + */ @DFBuilder -sealed class ItemDescriptor(val config: Config) { +public sealed class ItemDescriptor(public val config: Config) { /** * True if same name siblings with this name are allowed - * - * @return */ - var multiple: Boolean by config.boolean(false) + public var multiple: Boolean by config.boolean(false) /** - * The item description - * - * @return + * The item description text */ - var info: String? by config.string() + public var info: String? by config.string() /** * True if the item is required - * - * @return */ - abstract var required: Boolean + public abstract var required: Boolean /** @@ -34,29 +31,29 @@ sealed class ItemDescriptor(val config: Config) { * * @return */ - var attributes by config.node() -} + public var attributes: Config? by config.node() -/** - * Configure attributes of the descriptor - */ -fun ItemDescriptor.attributes(block: Config.() -> Unit) { - (attributes ?: Config().also { this.attributes = it }).apply(block) -} + /** + * An index field by which this node is identified in case of same name siblings construct + */ + public var indexKey: String by config.string(DEFAULT_INDEX_KEY) -/** - * Set specific attribute in the descriptor - */ -fun ItemDescriptor.setAttribute(name: Name, value: Any?) { - attributes { - set(name, value) + public companion object{ + public const val DEFAULT_INDEX_KEY: String = "@index" } } +/** + * Configure attributes of the descriptor, creating an attributes node if needed. + */ +public fun ItemDescriptor.attributes(block: Config.() -> Unit) { + (attributes ?: Config().also { this.attributes = it }).apply(block) +} + /** * Check if given item suits the descriptor */ -fun ItemDescriptor.validateItem(item: MetaItem<*>?): Boolean { +public fun ItemDescriptor.validateItem(item: MetaItem<*>?): Boolean { if (item == null) return !required return when (this) { is ValueDescriptor -> isAllowedValue(item.value ?: return false) @@ -73,7 +70,7 @@ fun ItemDescriptor.validateItem(item: MetaItem<*>?): Boolean { * @author Alexander Nozik */ @DFBuilder -class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) { +public class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) { init { config[IS_NODE_KEY] = true } @@ -90,14 +87,12 @@ class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) { * * @return */ - var default by config.node() + public var default: Config? by config.node() /** - * An index field by which this node is identified in case of same name siblings construct + * The map of children item descriptors (both nodes and values) */ - var indexKey by config.string(DEFAULT_INDEX_KEY) - - val items: Map<String, ItemDescriptor> + public val items: Map<String, ItemDescriptor> get() = config.getIndexed(ITEM_KEY).mapValues { (_, item) -> val node = item.node ?: error("Node descriptor must be a node") if (node[IS_NODE_KEY].boolean == true) { @@ -111,7 +106,7 @@ class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) { * The map of children node descriptors */ @Suppress("UNCHECKED_CAST") - val nodes: Map<String, NodeDescriptor> + public val nodes: Map<String, NodeDescriptor> get() = config.getIndexed(ITEM_KEY).entries.filter { it.value.node[IS_NODE_KEY].boolean == true }.associate { (name, item) -> @@ -120,9 +115,9 @@ class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) { } /** - * The list of value descriptors + * The list of children value descriptors */ - val values: Map<String, ValueDescriptor> + public val values: Map<String, ValueDescriptor> get() = config.getIndexed(ITEM_KEY).entries.filter { it.value.node[IS_NODE_KEY].boolean != true }.associate { (name, item) -> @@ -141,7 +136,7 @@ class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) { } NodeDescriptor(config) } - else -> buildNode(name.first()?.asName()!!).buildNode(name.cutFirst()) + else -> buildNode(name.firstOrNull()?.asName()!!).buildNode(name.cutFirst()) } } @@ -154,39 +149,43 @@ class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) { config[token] = descriptor.config } - fun item(name: Name, descriptor: ItemDescriptor) { - buildNode(name.cutLast()).newItem(name.last().toString(), descriptor) + public fun item(name: Name, descriptor: ItemDescriptor) { + buildNode(name.cutLast()).newItem(name.lastOrNull().toString(), descriptor) } - fun item(name: String, descriptor: ItemDescriptor) { + public fun item(name: String, descriptor: ItemDescriptor) { item(name.toName(), descriptor) } - fun node(name: Name, block: NodeDescriptor.() -> Unit) { + /** + * Create and configure a child node descriptor + */ + public fun node(name: Name, block: NodeDescriptor.() -> Unit) { item(name, NodeDescriptor().apply(block)) } - fun node(name: String, block: NodeDescriptor.() -> Unit) { + public fun node(name: String, block: NodeDescriptor.() -> Unit) { node(name.toName(), block) } - fun value(name: Name, block: ValueDescriptor.() -> Unit) { + /** + * Create and configure child value descriptor + */ + public fun value(name: Name, block: ValueDescriptor.() -> Unit) { require(name.length >= 1) { "Name length for value descriptor must be non-empty" } item(name, ValueDescriptor().apply(block)) } - fun value(name: String, block: ValueDescriptor.() -> Unit) { + public fun value(name: String, block: ValueDescriptor.() -> Unit) { value(name.toName(), block) } - companion object { + public companion object { - val ITEM_KEY = "item".asName() - val IS_NODE_KEY = "@isNode".asName() + internal val ITEM_KEY: Name = "item".asName() + internal val IS_NODE_KEY: Name = "@isNode".asName() - const val DEFAULT_INDEX_KEY = "@index" - - inline operator fun invoke(block: NodeDescriptor.() -> Unit) = NodeDescriptor().apply(block) + public inline operator fun invoke(block: NodeDescriptor.() -> Unit): NodeDescriptor = NodeDescriptor().apply(block) //TODO infer descriptor from spec } @@ -195,15 +194,15 @@ class NodeDescriptor(config: Config = Config()) : ItemDescriptor(config) { /** * Get a descriptor item associated with given name or null if item for given name not provided */ -operator fun ItemDescriptor.get(name: Name): ItemDescriptor? { +public operator fun ItemDescriptor.get(name: Name): ItemDescriptor? { if (name.isEmpty()) return this return when (this) { is ValueDescriptor -> null // empty name already checked - is NodeDescriptor -> items[name.first()!!.toString()]?.get(name.cutFirst()) + is NodeDescriptor -> items[name.firstOrNull()!!.toString()]?.get(name.cutFirst()) } } -operator fun ItemDescriptor.get(name: String): ItemDescriptor? = get(name.toName()) +public operator fun ItemDescriptor.get(name: String): ItemDescriptor? = get(name.toName()) /** * A descriptor for meta value @@ -213,7 +212,7 @@ operator fun ItemDescriptor.get(name: String): ItemDescriptor? = get(name.toName * @author Alexander Nozik */ @DFBuilder -class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) { +public class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) { /** * True if the value is required @@ -227,9 +226,9 @@ class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) { * * @return */ - var default: Value? by config.value() + public var default: Value? by config.value() - fun default(v: Any) { + public fun default(v: Any) { this.default = Value.of(v) } @@ -238,9 +237,9 @@ class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) { * * @return */ - var type: List<ValueType>? by config.listValue { ValueType.valueOf(it.string) } + public var type: List<ValueType>? by config.listValue { ValueType.valueOf(it.string) } - fun type(vararg t: ValueType) { + public fun type(vararg t: ValueType) { this.type = listOf(*t) } @@ -251,7 +250,7 @@ class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) { * @param value * @return */ - fun isAllowedValue(value: Value): Boolean { + public fun isAllowedValue(value: Value): Boolean { return (type?.let { it.contains(ValueType.STRING) || it.contains(value.type) } ?: true) && (allowedValues.isEmpty() || allowedValues.contains(value)) } @@ -262,7 +261,7 @@ class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) { * * @return */ - var allowedValues: List<Value> by config.item().convert( + public var allowedValues: List<Value> by config.item().convert( reader = { val value = it.value when { @@ -279,7 +278,7 @@ class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) { /** * Allow given list of value and forbid others */ - fun allow(vararg v: Any) { + public fun allow(vararg v: Any) { this.allowedValues = v.map { Value.of(it) } } } @@ -287,7 +286,7 @@ class ValueDescriptor(config: Config = Config()) : ItemDescriptor(config) { /** * Merge two node descriptors into one using first one as primary */ -operator fun NodeDescriptor.plus(other: NodeDescriptor): NodeDescriptor { +public operator fun NodeDescriptor.plus(other: NodeDescriptor): NodeDescriptor { return NodeDescriptor().apply { config.update(other.config) config.update(this@plus.config) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt new file mode 100644 index 00000000..20ce93dc --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/getIndexed.kt @@ -0,0 +1,36 @@ +package hep.dataforge.meta + +import hep.dataforge.names.* + +/** + * Get all items matching given name. The index of the last element, if present is used as a [Regex], + * against which indexes of elements are matched. + */ +public fun Meta.getIndexed(name: Name): Map<String?, MetaItem<*>> { + val root = when (name.length) { + 0 -> error("Can't use empty name for 'getIndexed'") + 1 -> this + else -> this[name.cutLast()].node ?: return emptyMap() + } + + val (body, index) = name.lastOrNull()!! + return if (index == null) { + root.items.filter { it.key.body == body }.mapKeys { it.key.index } + } else { + val regex = index.toRegex() + root.items.filter { it.key.body == body && (regex.matches(it.key.index ?: "")) } + .mapKeys { it.key.index } + } +} + +public fun Meta.getIndexed(name: String): Map<String?, MetaItem<*>> = this@getIndexed.getIndexed(name.toName()) + +/** + * Get all items matching given name. + */ +@Suppress("UNCHECKED_CAST") +public fun <M : MetaNode<M>> M.getIndexed(name: Name): Map<String, MetaItem<M>> = + (this as Meta).getIndexed(name) as Map<String, MetaItem<M>> + +public fun <M : MetaNode<M>> M.getIndexed(name: String): Map<String, MetaItem<M>> = + getIndexed(name.toName()) \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/mapMeta.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/mapMeta.kt index ed77f7f0..774a736a 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/mapMeta.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/mapMeta.kt @@ -8,7 +8,7 @@ import hep.dataforge.values.Value /** * Convert meta to map of maps */ -fun Meta.toMap(descriptor: NodeDescriptor? = null): Map<String, Any?> { +public fun Meta.toMap(descriptor: NodeDescriptor? = null): Map<String, Any?> { return items.entries.associate { (token, item) -> token.toString() to when (item) { is MetaItem.NodeItem -> item.node.toMap() @@ -22,7 +22,7 @@ fun Meta.toMap(descriptor: NodeDescriptor? = null): Map<String, Any?> { * All other values will be converted to values. */ @DFExperimental -fun Map<String, Any?>.toMeta(descriptor: NodeDescriptor? = null): Meta = Meta { +public fun Map<String, Any?>.toMeta(descriptor: NodeDescriptor? = null): Meta = Meta { @Suppress("UNCHECKED_CAST") fun toItem(value: Any?): MetaItem<*> = when (value) { is MetaItem<*> -> value diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/metaMatcher.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/metaMatcher.kt deleted file mode 100644 index f2f747db..00000000 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/metaMatcher.kt +++ /dev/null @@ -1,35 +0,0 @@ -package hep.dataforge.meta - -import hep.dataforge.names.Name -import hep.dataforge.names.toName - -/** - * Get all items matching given name. The index of the last element, if present is used as a [Regex], - * against which indexes of elements are matched. - */ -fun Meta.getIndexed(name: Name): Map<String, MetaItem<*>> { - val root = when (name.length) { - 0 -> error("Can't use empty name for 'getIndexed'") - 1 -> this - else -> this[name.cutLast()].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.getIndexed(name: String): Map<String, MetaItem<*>> = this@getIndexed.getIndexed(name.toName()) - -/** - * Get all items matching given name. - */ -@Suppress("UNCHECKED_CAST") -fun <M : MetaNode<M>> M.getIndexed(name: Name): Map<String, MetaItem<M>> = - (this as Meta).getIndexed(name) as Map<String, MetaItem<M>> - -fun <M : MetaNode<M>> M.getIndexed(name: String): Map<String, MetaItem<M>> = getIndexed(name.toName()) \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/propertyConverter.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/propertyConverter.kt deleted file mode 100644 index ebe55218..00000000 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/propertyConverter.kt +++ /dev/null @@ -1,83 +0,0 @@ -package hep.dataforge.meta - -import hep.dataforge.meta.transformations.MetaConverter -import kotlin.properties.ReadOnlyProperty -import kotlin.properties.ReadWriteProperty -import kotlin.reflect.KProperty - -/** - * Apply a converter to this delegate creating a delegate with a custom type - */ -fun <R : Any> ItemDelegate.convert( - converter: MetaConverter<R> -): ReadOnlyProperty<Any?, R?> = object : ReadOnlyProperty<Any?, R?> { - override fun getValue(thisRef: Any?, property: KProperty<*>): R? = - this@convert.getValue(thisRef, property)?.let(converter::itemToObject) -} - -/* - * - */ -fun <R : Any> ItemDelegate.convert( - converter: MetaConverter<R>, - default: () -> R -): ReadOnlyProperty<Any?, R> = object : ReadOnlyProperty<Any?, R> { - override fun getValue(thisRef: Any?, property: KProperty<*>): R = - this@convert.getValue(thisRef, property)?.let(converter::itemToObject) ?: default() -} - -/** - * A converter with a custom reader transformation - */ -fun <R> ItemDelegate.convert( - reader: (MetaItem<*>?) -> R -): ReadOnlyProperty<Any?, R> = object : ReadOnlyProperty<Any?, R> { - override fun getValue(thisRef: Any?, property: KProperty<*>): R = - this@convert.getValue(thisRef, property).let(reader) -} - -/*Mutable converters*/ - -/** - * A type converter for a mutable [MetaItem] delegate - */ -fun <R : Any> MutableItemDelegate.convert( - converter: MetaConverter<R> -): ReadWriteProperty<Any?, R?> = object : ReadWriteProperty<Any?, R?> { - - override fun getValue(thisRef: Any?, property: KProperty<*>): R? = - this@convert.getValue(thisRef, property)?.let(converter::itemToObject) - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: R?) { - val item = value?.let(converter::objectToMetaItem) - this@convert.setValue(thisRef, property, item) - } -} - -fun <R : Any> MutableItemDelegate.convert( - converter: MetaConverter<R>, - default: () -> R -): ReadWriteProperty<Any?, R> = object : ReadWriteProperty<Any?, R> { - - override fun getValue(thisRef: Any?, property: KProperty<*>): R = - this@convert.getValue(thisRef, property)?.let(converter::itemToObject) ?: default() - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: R) { - val item = value.let(converter::objectToMetaItem) - this@convert.setValue(thisRef, property, item) - } -} - -fun <R> MutableItemDelegate.convert( - reader: (MetaItem<*>?) -> R, - writer: (R) -> MetaItem<*>? -): ReadWriteProperty<Any?, R> = object : ReadWriteProperty<Any?, R> { - - override fun getValue(thisRef: Any?, property: KProperty<*>): R = - this@convert.getValue(thisRef, property).let(reader) - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: R) { - val item = value?.let(writer) - this@convert.setValue(thisRef, property, item) - } -} diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/serializationUtils.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/serializationUtils.kt deleted file mode 100644 index f06bb06a..00000000 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/serializationUtils.kt +++ /dev/null @@ -1,72 +0,0 @@ -package hep.dataforge.meta - -import kotlinx.serialization.* -import kotlinx.serialization.builtins.DoubleArraySerializer -import kotlinx.serialization.builtins.serializer -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration - -fun SerialDescriptorBuilder.boolean(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = - element(name, Boolean.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList()) - -fun SerialDescriptorBuilder.string(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = - element(name, String.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList()) - -fun SerialDescriptorBuilder.int(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = - element(name, Int.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList()) - -fun SerialDescriptorBuilder.double(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = - element(name, Double.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList()) - -fun SerialDescriptorBuilder.float(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = - element(name, Float.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList()) - -fun SerialDescriptorBuilder.long(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = - element(name, Long.serializer().descriptor, isOptional = isOptional, annotations = annotations.toList()) - -fun SerialDescriptorBuilder.doubleArray(name: String, isOptional: Boolean = false, vararg annotations: Annotation) = - element(name, DoubleArraySerializer().descriptor, isOptional = isOptional, annotations = annotations.toList()) - -@OptIn(InternalSerializationApi::class) -inline fun <reified E : Enum<E>> SerialDescriptorBuilder.enum( - name: String, - isOptional: Boolean = false, - vararg annotations: Annotation -) { - val enumDescriptor = SerialDescriptor(serialName, UnionKind.ENUM_KIND) { - enumValues<E>().forEach { - val fqn = "$serialName.${it.name}" - val enumMemberDescriptor = SerialDescriptor(fqn, StructureKind.OBJECT) - element(it.name, enumMemberDescriptor) - } - } - element(name, enumDescriptor, isOptional = isOptional, annotations = annotations.toList()) -} - -@DFExperimental -inline fun <R> Decoder.decodeStructure( - desc: SerialDescriptor, - vararg typeParams: KSerializer<*> = emptyArray(), - crossinline block: CompositeDecoder.() -> R -): R { - val decoder = beginStructure(desc, *typeParams) - val res = decoder.block() - decoder.endStructure(desc) - return res -} - -@DFExperimental -inline fun Encoder.encodeStructure( - desc: SerialDescriptor, - vararg typeParams: KSerializer<*> = emptyArray(), - block: CompositeEncoder.() -> Unit -) { - val encoder = beginStructure(desc, *typeParams) - encoder.block() - encoder.endStructure(desc) -} - -@OptIn(UnstableDefault::class) -val JSON_PRETTY = Json(JsonConfiguration(prettyPrint = true, useArrayPolymorphism = true)) -@OptIn(UnstableDefault::class) -val JSON_PLAIN = Json(JsonConfiguration(prettyPrint = true, useArrayPolymorphism = true)) \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaConverter.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaConverter.kt index 931e7cf3..0e4d6261 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaConverter.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaConverter.kt @@ -6,18 +6,18 @@ import hep.dataforge.values.* /** * A converter of generic object to and from [MetaItem] */ -interface MetaConverter<T : Any> { - fun itemToObject(item: MetaItem<*>): T - fun objectToMetaItem(obj: T): MetaItem<*> +public interface MetaConverter<T : Any> { + public fun itemToObject(item: MetaItem<*>): T + public fun objectToMetaItem(obj: T): MetaItem<*> - companion object { + public companion object { - val item = object : MetaConverter<MetaItem<*>> { + public val item: MetaConverter<MetaItem<*>> = object : MetaConverter<MetaItem<*>> { override fun itemToObject(item: MetaItem<*>): MetaItem<*> = item override fun objectToMetaItem(obj: MetaItem<*>): MetaItem<*> = obj } - val meta = object : MetaConverter<Meta> { + public val meta: MetaConverter<Meta> = object : MetaConverter<Meta> { override fun itemToObject(item: MetaItem<*>): Meta = when (item) { is MetaItem.NodeItem -> item.node is MetaItem.ValueItem -> item.value.toMeta() @@ -26,7 +26,7 @@ interface MetaConverter<T : Any> { override fun objectToMetaItem(obj: Meta): MetaItem<*> = MetaItem.NodeItem(obj) } - val value = object : MetaConverter<Value> { + public val value: MetaConverter<Value> = object : MetaConverter<Value> { override fun itemToObject(item: MetaItem<*>): Value = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -35,7 +35,7 @@ interface MetaConverter<T : Any> { override fun objectToMetaItem(obj: Value): MetaItem<*> = MetaItem.ValueItem(obj) } - val string = object : MetaConverter<String> { + public val string: MetaConverter<String> = object : MetaConverter<String> { override fun itemToObject(item: MetaItem<*>): String = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -44,7 +44,7 @@ interface MetaConverter<T : Any> { override fun objectToMetaItem(obj: String): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val boolean = object : MetaConverter<Boolean> { + public val boolean: MetaConverter<Boolean> = object : MetaConverter<Boolean> { override fun itemToObject(item: MetaItem<*>): Boolean = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -53,7 +53,7 @@ interface MetaConverter<T : Any> { override fun objectToMetaItem(obj: Boolean): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val number = object : MetaConverter<Number> { + public val number: MetaConverter<Number> = object : MetaConverter<Number> { override fun itemToObject(item: MetaItem<*>): Number = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -62,7 +62,7 @@ interface MetaConverter<T : Any> { override fun objectToMetaItem(obj: Number): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val double = object : MetaConverter<Double> { + public val double: MetaConverter<Double> = object : MetaConverter<Double> { override fun itemToObject(item: MetaItem<*>): Double = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -71,7 +71,7 @@ interface MetaConverter<T : Any> { override fun objectToMetaItem(obj: Double): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val float = object : MetaConverter<Float> { + public val float: MetaConverter<Float> = object : MetaConverter<Float> { override fun itemToObject(item: MetaItem<*>): Float = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -80,7 +80,7 @@ interface MetaConverter<T : Any> { override fun objectToMetaItem(obj: Float): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val int = object : MetaConverter<Int> { + public val int: MetaConverter<Int> = object : MetaConverter<Int> { override fun itemToObject(item: MetaItem<*>): Int = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -89,7 +89,7 @@ interface MetaConverter<T : Any> { override fun objectToMetaItem(obj: Int): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - val long = object : MetaConverter<Long> { + public val long: MetaConverter<Long> = object : MetaConverter<Long> { override fun itemToObject(item: MetaItem<*>): Long = when (item) { is MetaItem.NodeItem -> item.node[Meta.VALUE_KEY].value ?: error("Can't convert node to a value") is MetaItem.ValueItem -> item.value @@ -98,14 +98,14 @@ interface MetaConverter<T : Any> { override fun objectToMetaItem(obj: Long): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - inline fun <reified E : Enum<E>> enum(): MetaConverter<E> = object : MetaConverter<E> { + public inline fun <reified E : Enum<E>> enum(): MetaConverter<E> = object : MetaConverter<E> { @Suppress("USELESS_CAST") override fun itemToObject(item: MetaItem<*>): E = item.enum<E>() as? E ?: error("The Item is not a Enum") override fun objectToMetaItem(obj: E): MetaItem<*> = MetaItem.ValueItem(obj.asValue()) } - fun <T> valueList(writer: (T) -> Value = {Value.of(it)}, reader: (Value) -> T): MetaConverter<List<T>> = + public fun <T> valueList(writer: (T) -> Value = {Value.of(it)}, reader: (Value) -> T): MetaConverter<List<T>> = object : MetaConverter<List<T>> { override fun itemToObject(item: MetaItem<*>): List<T> = item.value?.list?.map(reader) ?: error("The item is not a value list") @@ -117,8 +117,8 @@ interface MetaConverter<T : Any> { } } -fun <T : Any> MetaConverter<T>.nullableItemToObject(item: MetaItem<*>?): T? = item?.let { itemToObject(it) } -fun <T : Any> MetaConverter<T>.nullableObjectToMetaItem(obj: T?): MetaItem<*>? = obj?.let { objectToMetaItem(it) } +public fun <T : Any> MetaConverter<T>.nullableItemToObject(item: MetaItem<*>?): T? = item?.let { itemToObject(it) } +public fun <T : Any> MetaConverter<T>.nullableObjectToMetaItem(obj: T?): MetaItem<*>? = obj?.let { objectToMetaItem(it) } -fun <T : Any> MetaConverter<T>.metaToObject(meta: Meta): T = itemToObject(MetaItem.NodeItem(meta)) -fun <T : Any> MetaConverter<T>.valueToObject(value: Value): T = itemToObject(MetaItem.ValueItem(value)) +public fun <T : Any> MetaConverter<T>.metaToObject(meta: Meta): T = itemToObject(MetaItem.NodeItem(meta)) +public fun <T : Any> MetaConverter<T>.valueToObject(value: Value): T = itemToObject(MetaItem.ValueItem(value)) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt index 38984520..9529b28e 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/meta/transformations/MetaTransformation.kt @@ -6,31 +6,31 @@ import hep.dataforge.names.Name /** * A transformation for meta item or a group of items */ -interface TransformationRule { +public interface TransformationRule { /** * Check if this transformation should be applied to a node with given name and value */ - fun matches(name: Name, item: MetaItem<*>?): Boolean + public fun matches(name: Name, item: MetaItem<*>?): Boolean /** * Select all items to be transformed. Item could be a value as well as node * * @return a sequence of item paths to be transformed */ - fun selectItems(meta: Meta): Sequence<Name> = + public fun selectItems(meta: Meta): Sequence<Name> = meta.sequence().filter { matches(it.first, it.second) }.map { it.first } /** * Apply transformation for a single item (Node or Value) to the target */ - fun <M : MutableMeta<M>> transformItem(name: Name, item: MetaItem<*>?, target: M): Unit + public fun <M : MutableMeta<M>> transformItem(name: Name, item: MetaItem<*>?, target: M): Unit } /** * A transformation which keeps all elements, matching [selector] unchanged. */ -data class KeepTransformationRule(val selector: (Name) -> Boolean) : +public data class KeepTransformationRule(val selector: (Name) -> Boolean) : TransformationRule { override fun matches(name: Name, item: MetaItem<*>?): Boolean { return selector(name) @@ -47,7 +47,7 @@ data class KeepTransformationRule(val selector: (Name) -> Boolean) : /** * A transformation which transforms element with specific name */ -data class SingleItemTransformationRule( +public data class SingleItemTransformationRule( val from: Name, val transform: MutableMeta<*>.(Name, MetaItem<*>?) -> Unit ) : TransformationRule { @@ -64,7 +64,7 @@ data class SingleItemTransformationRule( } } -data class RegexItemTransformationRule( +public data class RegexItemTransformationRule( val from: Regex, val transform: MutableMeta<*>.(name: Name, MatchResult, MetaItem<*>?) -> Unit ) : TransformationRule { @@ -84,12 +84,12 @@ data class RegexItemTransformationRule( /** * A set of [TransformationRule] to either transform static meta or create dynamically updated [MutableMeta] */ -inline class MetaTransformation(val transformations: Collection<TransformationRule>) { +public inline class MetaTransformation(public val transformations: Collection<TransformationRule>) { /** * Produce new meta using only those items that match transformation rules */ - fun generate(source: Meta): Meta = + public fun generate(source: Meta): Meta = Meta { transformations.forEach { rule -> rule.selectItems(source).forEach { name -> @@ -102,7 +102,7 @@ inline class MetaTransformation(val transformations: Collection<TransformationRu * Generate an observable configuration that contains only elements defined by transformation rules and changes with the source */ @DFExperimental - fun generate(source: Config): ObservableMeta = Config().apply { + public fun generate(source: Config): ObservableMeta = Config().apply { transformations.forEach { rule -> rule.selectItems(source).forEach { name -> rule.transformItem(name, source[name], this) @@ -115,7 +115,7 @@ inline class MetaTransformation(val transformations: Collection<TransformationRu /** * Transform a meta, replacing all elements found in rules with transformed entries */ - fun apply(source: Meta): Meta = + public fun apply(source: Meta): Meta = source.edit { transformations.forEach { rule -> rule.selectItems(source).forEach { name -> @@ -128,7 +128,7 @@ inline class MetaTransformation(val transformations: Collection<TransformationRu /** * Listens for changes in the source node and translates them into second node if transformation set contains a corresponding rule. */ - fun <M : MutableMeta<M>> bind(source: Config, target: M) { + public fun <M : MutableMeta<M>> bind(source: Config, target: M) { source.onChange(target) { name, _, newItem -> transformations.forEach { t -> if (t.matches(name, newItem)) { @@ -138,8 +138,8 @@ inline class MetaTransformation(val transformations: Collection<TransformationRu } } - companion object { - fun make(block: MetaTransformationBuilder.() -> Unit): MetaTransformation = + public companion object { + public fun make(block: MetaTransformationBuilder.() -> Unit): MetaTransformation = MetaTransformationBuilder().apply(block).build() } } @@ -147,27 +147,27 @@ inline class MetaTransformation(val transformations: Collection<TransformationRu /** * A builder for a set of transformation rules */ -class MetaTransformationBuilder { - val transformations = HashSet<TransformationRule>() +public class MetaTransformationBuilder { + private val transformations = HashSet<TransformationRule>() /** * Keep all items with name satisfying the criteria */ - fun keep(selector: (Name) -> Boolean) { + public fun keep(selector: (Name) -> Boolean) { transformations.add(KeepTransformationRule(selector)) } /** * Keep specific item (including its descendants) */ - fun keep(name: Name) { + public fun keep(name: Name) { keep { it == name } } /** * Keep nodes by regex */ - fun keep(regex: String) { + public fun keep(regex: String) { transformations.add( RegexItemTransformationRule(regex.toRegex()) { name, _, metaItem -> setItem(name, metaItem) @@ -177,7 +177,7 @@ class MetaTransformationBuilder { /** * Move an item from [from] to [to], optionally applying [operation] it defined */ - fun move(from: Name, to: Name, operation: (MetaItem<*>?) -> Any? = { it }) { + public fun move(from: Name, to: Name, operation: (MetaItem<*>?) -> Any? = { it }) { transformations.add( SingleItemTransformationRule(from) { _, item -> set(to, operation(item)) @@ -185,5 +185,5 @@ class MetaTransformationBuilder { ) } - fun build() = MetaTransformation(transformations) + public fun build(): MetaTransformation = MetaTransformation(transformations) } \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt index b3f8231a..9cce4314 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/Name.kt @@ -1,6 +1,12 @@ package hep.dataforge.names -import kotlinx.serialization.* +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder /** @@ -8,32 +14,9 @@ import kotlinx.serialization.* * The name is a dot separated list of strings like `token1.token2.token3`. * Each token could contain additional index in square brackets. */ -@Serializable -class Name(val tokens: List<NameToken>) { - - val length get() = tokens.size - - /** - * First token of the name or null if it is empty - */ - fun first(): NameToken? = tokens.firstOrNull() - - /** - * Last token of the name or null if it is empty - */ - fun last(): NameToken? = tokens.lastOrNull() - - /** - * 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. For empty name return itself. - */ - fun cutLast(): Name = Name(tokens.dropLast(1)) - - operator fun get(i: Int): NameToken = tokens[i] +@Serializable(Name.Companion::class) +public class Name(public val tokens: List<NameToken>) { + //TODO to be transformed into inline class after they are supported with serialization override fun toString(): String = tokens.joinToString(separator = NAME_SEPARATOR) { it.toString() } @@ -53,14 +36,13 @@ class Name(val tokens: List<NameToken>) { } } - @Serializer(Name::class) - companion object : KSerializer<Name> { - const val NAME_SEPARATOR = "." + public companion object : KSerializer<Name> { + public const val NAME_SEPARATOR: String = "." - val EMPTY = Name(emptyList()) + public val EMPTY: Name = Name(emptyList()) override val descriptor: SerialDescriptor = - PrimitiveDescriptor("hep.dataforge.names.Name", PrimitiveKind.STRING) + PrimitiveSerialDescriptor("hep.dataforge.names.Name", PrimitiveKind.STRING) override fun deserialize(decoder: Decoder): Name { return decoder.decodeString().toName() @@ -72,54 +54,36 @@ class Name(val tokens: List<NameToken>) { } } +public operator fun Name.get(i: Int): NameToken = tokens[i] + /** - * A single name token. Body is not allowed to be empty. - * Following symbols are prohibited in name tokens: `{}.:\`. - * A name token could have appendix in square brackets called *index* + * The reminder of the name after last element is cut. For empty name return itself. */ -@Serializable -data class NameToken(val body: String, val index: String = "") { +public fun Name.cutLast(): Name = Name(tokens.dropLast(1)) - init { - if (body.isEmpty()) error("Syntax error: Name token body is empty") - } +/** + * The reminder of the name after first element is cut. For empty name return itself. + */ +public fun Name.cutFirst(): Name = Name(tokens.drop(1)) - private fun String.escape() = - replace("\\", "\\\\") - .replace(".", "\\.") - .replace("[", "\\[") - .replace("]", "\\]") +public val Name.length: Int get() = tokens.size - override fun toString(): String = if (hasIndex()) { - "${body.escape()}[$index]" - } else { - body.escape() - } +/** + * Last token of the name or null if it is empty + */ +public fun Name.lastOrNull(): NameToken? = tokens.lastOrNull() - fun hasIndex() = index.isNotEmpty() +/** + * First token of the name or null if it is empty + */ +public fun Name.firstOrNull(): NameToken? = tokens.firstOrNull() - @Serializer(NameToken::class) - companion object : KSerializer<NameToken> { - override val descriptor: SerialDescriptor = - PrimitiveDescriptor("hep.dataforge.names.NameToken", PrimitiveKind.STRING) - - override fun deserialize(decoder: Decoder): NameToken { - return decoder.decodeString().toName().first()!! - } - - override fun serialize(encoder: Encoder, value: NameToken) { - encoder.encodeString(value.toString()) - } - } -} - -fun NameToken.withIndex(newIndex: String) = NameToken(body, newIndex) /** * Convert a [String] to name parsing it and extracting name tokens and index syntax. * This operation is rather heavy so it should be used with care in high performance code. */ -fun String.toName(): Name { +public fun String.toName(): Name { if (isBlank()) return Name.EMPTY val tokens = sequence { var bodyBuilder = StringBuilder() @@ -150,7 +114,8 @@ fun String.toName(): Name { } else -> when (it) { '.' -> { - yield(NameToken(bodyBuilder.toString(), queryBuilder.toString())) + val query = if(queryBuilder.isEmpty()) null else queryBuilder.toString() + yield(NameToken(bodyBuilder.toString(), query)) bodyBuilder = StringBuilder() queryBuilder = StringBuilder() } @@ -163,7 +128,8 @@ fun String.toName(): Name { } } } - yield(NameToken(bodyBuilder.toString(), queryBuilder.toString())) + val query = if(queryBuilder.isEmpty()) null else queryBuilder.toString() + yield(NameToken(bodyBuilder.toString(), query)) } return Name(tokens.toList()) } @@ -172,26 +138,26 @@ fun String.toName(): Name { * Convert the [String] to a [Name] by simply wrapping it in a single name token without parsing. * The input string could contain dots and braces, but they are just escaped, not parsed. */ -fun String.asName(): Name = if (isBlank()) Name.EMPTY else NameToken(this).asName() +public fun String.asName(): Name = if (isBlank()) Name.EMPTY else NameToken(this).asName() -operator fun NameToken.plus(other: Name): Name = Name(listOf(this) + other.tokens) +public operator fun NameToken.plus(other: Name): Name = Name(listOf(this) + other.tokens) -operator fun Name.plus(other: Name): Name = Name(this.tokens + other.tokens) +public operator fun Name.plus(other: Name): Name = Name(this.tokens + other.tokens) -operator fun Name.plus(other: String): Name = this + other.toName() +public operator fun Name.plus(other: String): Name = this + other.toName() -operator fun Name.plus(other: NameToken): Name = Name(tokens + other) +public operator fun Name.plus(other: NameToken): Name = Name(tokens + other) -fun Name.appendLeft(other: String): Name = NameToken(other) + this +public fun Name.appendLeft(other: String): Name = NameToken(other) + this -fun NameToken.asName() = Name(listOf(this)) +public fun NameToken.asName(): Name = Name(listOf(this)) -fun Name.isEmpty(): Boolean = this.length == 0 +public fun Name.isEmpty(): Boolean = this.length == 0 /** * Set or replace last token index */ -fun Name.withIndex(index: String): Name { +public fun Name.withIndex(index: String): Name { val last = NameToken(tokens.last().body, index) if (length == 0) error("Can't add index to empty name") if (length == 1) { @@ -206,19 +172,19 @@ fun Name.withIndex(index: String): Name { /** * Fast [String]-based accessor for item map */ -operator fun <T> Map<NameToken, T>.get(body: String, query: String = ""): T? = get(NameToken(body, query)) +public operator fun <T> Map<NameToken, T>.get(body: String, query: String? = null): T? = get(NameToken(body, query)) -operator fun <T> Map<Name, T>.get(name: String) = get(name.toName()) -operator fun <T> MutableMap<Name, T>.set(name: String, value: T) = set(name.toName(), value) +public operator fun <T> Map<Name, T>.get(name: String): T? = get(name.toName()) +public operator fun <T> MutableMap<Name, T>.set(name: String, value: T): Unit = set(name.toName(), value) /* Name comparison operations */ -fun Name.startsWith(token: NameToken): Boolean = first() == token +public fun Name.startsWith(token: NameToken): Boolean = firstOrNull() == token -fun Name.endsWith(token: NameToken): Boolean = last() == token +public fun Name.endsWith(token: NameToken): Boolean = lastOrNull() == token -fun Name.startsWith(name: Name): Boolean = +public fun Name.startsWith(name: Name): Boolean = this.length >= name.length && tokens.subList(0, name.length) == name.tokens -fun Name.endsWith(name: Name): Boolean = +public fun Name.endsWith(name: Name): Boolean = this.length >= name.length && tokens.subList(length - name.length, length) == name.tokens \ No newline at end of file diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/NameToken.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/NameToken.kt new file mode 100644 index 00000000..d010ac5a --- /dev/null +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/names/NameToken.kt @@ -0,0 +1,60 @@ +package hep.dataforge.names + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +/** + * A single name token. Body is not allowed to be empty. + * Following symbols are prohibited in name tokens: `{}.:\`. + * A name token could have appendix in square brackets called *index* + */ +@Serializable(NameToken.Companion::class) +public data class NameToken(val body: String, val index: String? = null) { + + init { + if (body.isEmpty()) error("Syntax error: Name token body is empty") + } + + private fun String.escape() = + replace("\\", "\\\\") + .replace(".", "\\.") + .replace("[", "\\[") + .replace("]", "\\]") + + override fun toString(): String = if (hasIndex()) { + "${body.escape()}[$index]" + } else { + body.escape() + } + + public companion object : KSerializer<NameToken> { + override val descriptor: SerialDescriptor = + PrimitiveSerialDescriptor("hep.dataforge.names.NameToken", PrimitiveKind.STRING) + + override fun deserialize(decoder: Decoder): NameToken { + return decoder.decodeString().toName().firstOrNull()!! + } + + override fun serialize( + encoder: Encoder, + value: NameToken, + ) { + encoder.encodeString(value.toString()) + } + } +} + +/** + * Check if index is defined for this token + */ +public fun NameToken.hasIndex(): Boolean = index != null + +/** + * Add or replace index part of this token + */ +public fun NameToken.withIndex(newIndex: String): NameToken = NameToken(body, newIndex) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/Value.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/Value.kt index 05c082e9..ca78f0ae 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/Value.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/Value.kt @@ -10,7 +10,7 @@ import kotlinx.serialization.Serializable * */ @Serializable -enum class ValueType { +public enum class ValueType { NUMBER, STRING, BOOLEAN, NULL } @@ -19,44 +19,44 @@ enum class ValueType { * * Value can represent a list of value objects. */ -interface Value { +@Serializable(ValueSerializer::class) +public interface Value { /** * Get raw value of this value */ - val value: Any? + public val value: Any? /** * The type of the value */ - val type: ValueType + public val type: ValueType /** * get this value represented as Number */ - val number: Number + public val number: Number /** * get this value represented as String */ - val string: String + public val string: String /** * get this value represented as List */ - val list: List<Value> - get() = if (this == Null) emptyList() else listOf(this) + public val list: List<Value> get() = if (this == Null) emptyList() else listOf(this) override fun equals(other: Any?): Boolean override fun hashCode(): Int - companion object { - const val TYPE = "value" + public companion object { + public const val TARGET: String = "value" /** * Convert object to value */ - fun of(value: Any?): Value { + public fun of(value: Any?): Value { return when (value) { null -> Null is Value -> value @@ -89,7 +89,7 @@ interface Value { /** * A singleton null value */ -object Null : Value { +public object Null : Value { override val value: Any? get() = null override val type: ValueType get() = ValueType.NULL override val number: Number get() = Double.NaN @@ -104,7 +104,7 @@ object Null : Value { /** * Singleton true value */ -object True : Value { +public object True : Value { override val value: Any? get() = true override val type: ValueType get() = ValueType.BOOLEAN override val number: Number get() = 1.0 @@ -119,7 +119,7 @@ object True : Value { /** * Singleton false value */ -object False : Value { +public object False : Value { override val value: Any? get() = false override val type: ValueType get() = ValueType.BOOLEAN override val number: Number get() = -1.0 @@ -131,7 +131,7 @@ object False : Value { override fun hashCode(): Int = -1 } -class NumberValue(override val number: Number) : Value { +public class NumberValue(override val number: Number) : Value { override val value: Any? get() = number override val type: ValueType get() = ValueType.NUMBER override val string: String get() = number.toString() @@ -154,7 +154,7 @@ class NumberValue(override val number: Number) : Value { override fun toString(): String = value.toString() } -class StringValue(override val string: String) : Value { +public class StringValue(override val string: String) : Value { override val value: Any? get() = string override val type: ValueType get() = ValueType.STRING override val number: Number get() = string.toDouble() @@ -168,7 +168,7 @@ class StringValue(override val string: String) : Value { override fun toString(): String = "\"${value.toString()}\"" } -class EnumValue<E : Enum<*>>(override val value: E) : Value { +public class EnumValue<E : Enum<*>>(override val value: E) : Value { override val type: ValueType get() = ValueType.STRING override val number: Number get() = value.ordinal override val string: String get() = value.name @@ -182,7 +182,7 @@ class EnumValue<E : Enum<*>>(override val value: E) : Value { override fun toString(): String = value.toString() } -class ListValue(override val list: List<Value>) : Value { +public class ListValue(override val list: List<Value>) : Value { init { require(list.isNotEmpty()) { "Can't create list value from empty list" } } @@ -210,34 +210,34 @@ class ListValue(override val list: List<Value>) : Value { } -fun Number.asValue(): Value = NumberValue(this) +public fun Number.asValue(): Value = NumberValue(this) -fun Boolean.asValue(): Value = if (this) True else False +public fun Boolean.asValue(): Value = if (this) True else False -fun String.asValue(): Value = StringValue(this) +public fun String.asValue(): Value = StringValue(this) -fun Iterable<Value>.asValue(): Value { +public fun Iterable<Value>.asValue(): Value { val list = toList() return if (list.isEmpty()) Null else ListValue(this.toList()) } -fun IntArray.asValue(): Value = if (isEmpty()) Null else ListValue(map { NumberValue(it) }) +public fun IntArray.asValue(): Value = if (isEmpty()) Null else ListValue(map { NumberValue(it) }) -fun LongArray.asValue(): Value = if (isEmpty()) Null else ListValue(map { NumberValue(it) }) +public fun LongArray.asValue(): Value = if (isEmpty()) Null else ListValue(map { NumberValue(it) }) -fun ShortArray.asValue(): Value = if (isEmpty()) Null else ListValue(map { NumberValue(it) }) +public fun ShortArray.asValue(): Value = if (isEmpty()) Null else ListValue(map { NumberValue(it) }) -fun FloatArray.asValue(): Value = if (isEmpty()) Null else ListValue(map { NumberValue(it) }) +public fun FloatArray.asValue(): Value = if (isEmpty()) Null else ListValue(map { NumberValue(it) }) -fun ByteArray.asValue(): Value = if (isEmpty()) Null else ListValue(map { NumberValue(it) }) +public fun ByteArray.asValue(): Value = if (isEmpty()) Null else ListValue(map { NumberValue(it) }) -fun <E : Enum<E>> E.asValue(): Value = EnumValue(this) +public fun <E : Enum<E>> E.asValue(): Value = EnumValue(this) /** * Create Value from String using closest match conversion */ -fun String.parseValue(): Value { +public fun String.parseValue(): Value { //Trying to get integer if (isEmpty() || this == Null.string) { diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/ValueSerializer.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/ValueSerializer.kt index 8055b554..08b87c18 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/ValueSerializer.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/ValueSerializer.kt @@ -1,24 +1,25 @@ 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 +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.descriptors.element +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder -@Serializer(Value::class) -object ValueSerializer : KSerializer<Value> { - private val listSerializer by lazy { ValueSerializer.list } +public object ValueSerializer : KSerializer<Value> { + private val listSerializer by lazy { ListSerializer(ValueSerializer) } override val descriptor: SerialDescriptor = - SerialDescriptor("hep.dataforge.values.Value") { - boolean("isList") - enum<ValueType>("valueType") - string("value") + buildClassSerialDescriptor("hep.dataforge.values.Value") { + element<Boolean>("isList") + element<ValueType>("valueType") + element<String>("value") } private fun Decoder.decodeValue(): Value { - return when (decode(ValueType.serializer())) { + return when (decodeSerializableValue(ValueType.serializer())) { ValueType.NULL -> Null ValueType.NUMBER -> decodeDouble().asValue() //TODO differentiate? ValueType.BOOLEAN -> decodeBoolean().asValue() @@ -37,7 +38,7 @@ object ValueSerializer : KSerializer<Value> { } private fun Encoder.encodeValue(value: Value) { - encode(ValueType.serializer(), value.type) + encodeSerializableValue(ValueType.serializer(), value.type) when (value.type) { ValueType.NULL -> { // do nothing diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/exoticValues.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/exoticValues.kt index d0fb86e8..4b04a036 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/exoticValues.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/exoticValues.kt @@ -4,7 +4,7 @@ package hep.dataforge.values /** * A value built from string which content and type are parsed on-demand */ -class LazyParsedValue(override val string: String) : Value { +public class LazyParsedValue(override val string: String) : Value { private val parsedValue by lazy { string.parseValue() } override val value: Any? get() = parsedValue.value @@ -18,12 +18,12 @@ class LazyParsedValue(override val string: String) : Value { override fun hashCode(): Int = string.hashCode() } -fun String.lazyParseValue(): LazyParsedValue = LazyParsedValue(this) +public fun String.lazyParseValue(): LazyParsedValue = LazyParsedValue(this) /** * A performance optimized version of list value for doubles */ -class DoubleArrayValue(override val value: DoubleArray) : Value { +public class DoubleArrayValue(override val value: DoubleArray) : Value { override val type: ValueType get() = ValueType.NUMBER override val number: Double get() = value.first() override val string: String get() = value.first().toString() @@ -46,4 +46,4 @@ class DoubleArrayValue(override val value: DoubleArray) : Value { override fun toString(): String = list.joinToString (prefix = "[", postfix = "]") } -fun DoubleArray.asValue(): Value = if(isEmpty()) Null else DoubleArrayValue(this) +public fun DoubleArray.asValue(): Value = if(isEmpty()) Null else DoubleArrayValue(this) diff --git a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/valueExtensions.kt b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/valueExtensions.kt index 3767e2fb..2171c4ea 100644 --- a/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/valueExtensions.kt +++ b/dataforge-meta/src/commonMain/kotlin/hep/dataforge/values/valueExtensions.kt @@ -1,32 +1,33 @@ package hep.dataforge.values import hep.dataforge.meta.Meta +import hep.dataforge.meta.MetaBuilder /** * Check if value is null */ -fun Value.isNull(): Boolean = this == Null +public fun Value.isNull(): Boolean = this == Null /** * Check if value is list */ -fun Value.isList(): Boolean = this.list.size > 1 +public fun Value.isList(): Boolean = this.list.size > 1 -val Value.boolean +public val Value.boolean: Boolean get() = this == True || this.list.firstOrNull() == True || (type == ValueType.STRING && string.toBoolean()) -val Value.int get() = number.toInt() -val Value.double get() = number.toDouble() -val Value.float get() = number.toFloat() -val Value.short get() = number.toShort() -val Value.long get() = number.toLong() +public val Value.int: Int get() = number.toInt() +public val Value.double: Double get() = number.toDouble() +public val Value.float: Float get() = number.toFloat() +public val Value.short: Short get() = number.toShort() +public val Value.long: Long get() = number.toLong() -val Value.stringList: List<String> get() = list.map { it.string } +public val Value.stringList: List<String> get() = list.map { it.string } -val Value.doubleArray: DoubleArray +public val Value.doubleArray: DoubleArray get() = if (this is DoubleArrayValue) { value } else { @@ -34,4 +35,4 @@ val Value.doubleArray: DoubleArray } -fun Value.toMeta() = Meta { Meta.VALUE_KEY put this } \ No newline at end of file +public fun Value.toMeta(): MetaBuilder = Meta { Meta.VALUE_KEY put this } \ No newline at end of file diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/ConfigTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/ConfigTest.kt new file mode 100644 index 00000000..5e6341aa --- /dev/null +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/ConfigTest.kt @@ -0,0 +1,14 @@ +package hep.dataforge.meta + +import kotlin.test.Test +import kotlin.test.assertEquals + +class ConfigTest { + @Test + fun testIndexedWrite(){ + val config = Config() + config["a[1].b"] = 1 + assertEquals(null, config["a.b"].int) + assertEquals(1, config["a[1].b"].int) + } +} \ No newline at end of file diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/JsonMetaTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/JsonMetaTest.kt index 9086e156..2a1329a7 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/JsonMetaTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/JsonMetaTest.kt @@ -1,35 +1,33 @@ package hep.dataforge.meta import hep.dataforge.meta.descriptors.NodeDescriptor -import kotlinx.serialization.json.int -import kotlinx.serialization.json.json -import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.* import kotlin.test.Test import kotlin.test.assertEquals class JsonMetaTest { - val json = json { - "firstValue" to "a" - "secondValue" to "b" - "array" to jsonArray { - +"1" - +"2" - +"3" - } - "nodeArray" to jsonArray { - +json { - "index" to "1" - "value" to 2 - } - +json { - "index" to "2" - "value" to 3 - } - +json { - "index" to "3" - "value" to 4 - } - } + val json = buildJsonObject { + put("firstValue", "a") + put("secondValue", "b") + put("array", buildJsonArray { + add("1") + add("2") + add("3") + }) + put("nodeArray", buildJsonArray { + add(buildJsonObject { + put("index", "1") + put("value", 2) + }) + add(buildJsonObject { + put("index", "2") + put("value", 3) + }) + add(buildJsonObject { + put("index", "3") + put("value", 4) + }) + }) } val descriptor = NodeDescriptor{ @@ -45,7 +43,8 @@ class JsonMetaTest { //println(meta) val reconstructed = meta.toJson(descriptor) println(reconstructed) - assertEquals(2, reconstructed["nodeArray"]?.jsonArray?.get(1)?.jsonObject?.get("index")?.int) + assertEquals(2, + reconstructed["nodeArray"]?.jsonArray?.get(1)?.jsonObject?.get("index")?.jsonPrimitive?.int) assertEquals(json,reconstructed) } } \ No newline at end of file diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt index 925ee36c..6b8442d1 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/MetaDelegateTest.kt @@ -1,5 +1,6 @@ package hep.dataforge.meta +import hep.dataforge.values.asValue import kotlin.test.Test import kotlin.test.assertEquals @@ -29,7 +30,7 @@ class MetaDelegateTest { fun delegateTest() { val testObject = TestScheme.empty() - testObject.config["myValue"] = "theString" + testObject.setValue("myValue","theString".asValue()) testObject.enumValue = TestEnum.NO testObject.inner = InnerSpec { innerValue = "ddd" } diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt index f21c5b2c..587e2049 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/SpecificationTest.kt @@ -1,19 +1,18 @@ package hep.dataforge.meta -import hep.dataforge.names.Name import kotlin.test.Test import kotlin.test.assertEquals class SpecificationTest { - class TestStyled(config: Config, defaultProvider: (Name) -> MetaItem<*>?) : - Scheme(config, defaultProvider) { + class TestStyled : Scheme() { var list by numberList(1, 2, 3) companion object : Specification<TestStyled> { - override fun wrap( - config: Config, - defaultProvider: (Name) -> MetaItem<*>? - ): TestStyled = TestStyled(config, defaultProvider) + override fun read(meta: Meta, defaultProvider: ItemProvider): TestStyled = + TestStyled().apply { + this.config = meta.asConfig() + + } } } diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/descriptors/DescriptorTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/descriptors/DescriptorTest.kt index 605cbebd..6d2c3ca5 100644 --- a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/descriptors/DescriptorTest.kt +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/meta/descriptors/DescriptorTest.kt @@ -36,7 +36,7 @@ class DescriptorTest { @Test fun testDefaultMetaNode(){ - val meta = descriptor.buildDefaultMeta() + val meta = descriptor.defaultMeta() assertEquals(false, meta["aNode.otherNode.otherValue"].boolean) } } \ No newline at end of file diff --git a/dataforge-meta/src/commonTest/kotlin/hep/dataforge/names/NameSerializationTest.kt b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/names/NameSerializationTest.kt new file mode 100644 index 00000000..7449be2f --- /dev/null +++ b/dataforge-meta/src/commonTest/kotlin/hep/dataforge/names/NameSerializationTest.kt @@ -0,0 +1,18 @@ +package hep.dataforge.names + +import kotlinx.serialization.json.Json +import kotlin.test.Test +import kotlin.test.assertEquals + + +class NameSerializationTest { + + @Test + fun testNameSerialization() { + val name = "aaa.bbb.ccc".toName() + val json = Json.encodeToJsonElement(Name.serializer(), name) + println(json) + val reconstructed = Json.decodeFromJsonElement(Name.serializer(), json) + assertEquals(name, reconstructed) + } +} \ No newline at end of file diff --git a/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt b/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt index ff23a571..9d76b606 100644 --- a/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt +++ b/dataforge-meta/src/jsMain/kotlin/hep/dataforge/meta/DynamicMeta.kt @@ -8,7 +8,7 @@ import hep.dataforge.values.isList //TODO add Meta wrapper for dynamic -fun Value.toDynamic(): dynamic { +public fun Value.toDynamic(): dynamic { return if (isList()) { list.map { it.toDynamic() }.toTypedArray().asDynamic() } else { @@ -19,7 +19,7 @@ fun Value.toDynamic(): dynamic { /** * Represent or copy this [Meta] to dynamic object to be passed to JS libraries */ -fun Meta.toDynamic(): dynamic { +public fun Meta.toDynamic(): dynamic { if (this is DynamicMeta) return this.obj fun MetaItem<*>.toDynamic(): dynamic = when (this) { @@ -38,8 +38,8 @@ fun Meta.toDynamic(): dynamic { return res } -class DynamicMeta(val obj: dynamic) : MetaBase() { - private fun keys() = js("Object.keys(this.obj)") as Array<String> +public class DynamicMeta(internal val obj: dynamic) : MetaBase() { + private fun keys(): Array<String> = js("Object").keys(obj) private fun isArray(@Suppress("UNUSED_PARAMETER") obj: dynamic): Boolean = js("Array.isArray(obj)") as Boolean @@ -47,7 +47,7 @@ class DynamicMeta(val obj: dynamic) : MetaBase() { private fun isPrimitive(obj: dynamic): Boolean = (jsTypeOf(obj) != "object") - @Suppress("UNCHECKED_CAST") + @Suppress("UNCHECKED_CAST", "USELESS_CAST") private fun asItem(obj: dynamic): MetaItem<DynamicMeta>? { return when { obj == null -> MetaItem.ValueItem(Null) diff --git a/dataforge-output/api/dataforge-output.api b/dataforge-output/api/dataforge-output.api new file mode 100644 index 00000000..f991b754 --- /dev/null +++ b/dataforge-output/api/dataforge-output.api @@ -0,0 +1,68 @@ +public final class hep/dataforge/output/ConsoleOutputManager : hep/dataforge/context/AbstractPlugin, hep/dataforge/output/OutputManager { + public static final field Companion Lhep/dataforge/output/ConsoleOutputManager$Companion; + public fun <init> ()V + public fun get (Lkotlin/reflect/KClass;Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)Lhep/dataforge/output/Renderer; + public fun getTag ()Lhep/dataforge/context/PluginTag; +} + +public final class hep/dataforge/output/ConsoleOutputManager$Companion : hep/dataforge/context/PluginFactory { + public fun getTag ()Lhep/dataforge/context/PluginTag; + public fun getType ()Lkotlin/reflect/KClass; + public fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Lhep/dataforge/output/ConsoleOutputManager; + public synthetic fun invoke (Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;)Ljava/lang/Object; +} + +public final class hep/dataforge/output/DefaultTextFormat : hep/dataforge/output/TextFormat { + public static final field INSTANCE Lhep/dataforge/output/DefaultTextFormat; + public fun getPriority ()I + public fun getType ()Lkotlin/reflect/KClass; + public fun render (Ljava/lang/Appendable;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class hep/dataforge/output/OutputJVMKt { + public static final fun getOutput (Lkotlinx/coroutines/Dispatchers;)Lkotlinx/coroutines/CoroutineDispatcher; +} + +public abstract interface class hep/dataforge/output/OutputManager { + public abstract fun get (Lkotlin/reflect/KClass;Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)Lhep/dataforge/output/Renderer; +} + +public final class hep/dataforge/output/OutputManager$DefaultImpls { + public static synthetic fun get$default (Lhep/dataforge/output/OutputManager;Lkotlin/reflect/KClass;Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/output/Renderer; +} + +public final class hep/dataforge/output/OutputManagerKt { + public static final fun getCONSOLE_RENDERER ()Lhep/dataforge/output/Renderer; + public static final fun getOutput (Lhep/dataforge/context/Context;)Lhep/dataforge/output/OutputManager; + public static final fun render (Lhep/dataforge/output/OutputManager;Ljava/lang/Object;Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V + public static synthetic fun render$default (Lhep/dataforge/output/OutputManager;Ljava/lang/Object;Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)V +} + +public abstract interface class hep/dataforge/output/Renderer : hep/dataforge/context/ContextAware { + public abstract fun render (Ljava/lang/Object;Lhep/dataforge/meta/Meta;)V +} + +public final class hep/dataforge/output/Renderer$DefaultImpls { + public static fun getLogger (Lhep/dataforge/output/Renderer;)Lmu/KLogger; + public static synthetic fun render$default (Lhep/dataforge/output/Renderer;Ljava/lang/Object;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)V +} + +public abstract interface class hep/dataforge/output/TextFormat { + public static final field Companion Lhep/dataforge/output/TextFormat$Companion; + public static final field TEXT_RENDERER_TYPE Ljava/lang/String; + public abstract fun getPriority ()I + public abstract fun getType ()Lkotlin/reflect/KClass; + public abstract fun render (Ljava/lang/Appendable;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class hep/dataforge/output/TextFormat$Companion { + public static final field TEXT_RENDERER_TYPE Ljava/lang/String; +} + +public final class hep/dataforge/output/TextRenderer : hep/dataforge/output/Renderer { + public fun <init> (Lhep/dataforge/context/Context;Ljava/lang/Appendable;)V + public fun getContext ()Lhep/dataforge/context/Context; + public fun getLogger ()Lmu/KLogger; + public fun render (Ljava/lang/Object;Lhep/dataforge/meta/Meta;)V +} + diff --git a/dataforge-output/build.gradle.kts b/dataforge-output/build.gradle.kts index 6c0a1e53..6051cb1c 100644 --- a/dataforge-output/build.gradle.kts +++ b/dataforge-output/build.gradle.kts @@ -1,5 +1,6 @@ plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") + id("ru.mipt.npm.native") } kotlin { @@ -7,7 +8,7 @@ kotlin { val commonMain by getting{ dependencies { api(project(":dataforge-context")) - api(project(":dataforge-io")) + //api(project(":dataforge-io")) } } } diff --git a/dataforge-output/dataforge-output-html/build.gradle.kts b/dataforge-output/dataforge-output-html/build.gradle.kts deleted file mode 100644 index 98b9d0bd..00000000 --- a/dataforge-output/dataforge-output-html/build.gradle.kts +++ /dev/null @@ -1,26 +0,0 @@ -plugins { - id("scientifik.mpp") -} - -val htmlVersion by rootProject.extra("0.6.12") - -kotlin { - sourceSets { - val commonMain by getting { - dependencies { - api(project(":dataforge-output")) - api("org.jetbrains.kotlinx:kotlinx-html-common:$htmlVersion") - } - } - val jsMain by getting { - dependencies { - api("org.jetbrains.kotlinx:kotlinx-html-js:$htmlVersion") - } - } - val jvmMain by getting{ - dependencies { - api("org.jetbrains.kotlinx:kotlinx-html-jvm:$htmlVersion") - } - } - } -} \ No newline at end of file diff --git a/dataforge-output/dataforge-output-html/src/commonMain/kotlin/hep/dataforge/output/html/HtmlRenderer.kt b/dataforge-output/dataforge-output-html/src/commonMain/kotlin/hep/dataforge/output/html/HtmlRenderer.kt deleted file mode 100644 index c0aeaaab..00000000 --- a/dataforge-output/dataforge-output-html/src/commonMain/kotlin/hep/dataforge/output/html/HtmlRenderer.kt +++ /dev/null @@ -1,79 +0,0 @@ -package hep.dataforge.output.html - -import hep.dataforge.context.Context -import hep.dataforge.meta.Meta -import hep.dataforge.output.Output -import hep.dataforge.output.Renderer -import hep.dataforge.output.TextFormat -import hep.dataforge.output.html.HtmlBuilder.Companion.HTML_CONVERTER_TYPE -import hep.dataforge.provider.Type -import hep.dataforge.provider.top -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.html.TagConsumer -import kotlinx.html.p -import kotlin.reflect.KClass - - -class HtmlRenderer<T : Any>(override val context: Context, private val consumer: TagConsumer<*>) : Renderer<T> { - private val cache = HashMap<KClass<*>, HtmlBuilder<*>>() - - /** - * Find the first [TextFormat] matching the given object type. - */ - override fun render(obj: T, meta: Meta) { - - val builder: HtmlBuilder<*> = if (obj is CharSequence) { - DefaultHtmlBuilder - } else { - val value = cache[obj::class] - if (value == null) { - val answer = - context.top<HtmlBuilder<*>>(HTML_CONVERTER_TYPE).values.firstOrNull { it.type.isInstance(obj) } - if (answer != null) { - cache[obj::class] = answer - answer - } else { - DefaultHtmlBuilder - } - } else { - value - } - } - context.launch(Dispatchers.Output) { - @Suppress("UNCHECKED_CAST") - (builder as HtmlBuilder<T>).run { consumer.render(obj) } - } - } -} - -/** - * A text or binary renderer based on [Renderer] - */ -@Type(HTML_CONVERTER_TYPE) -interface HtmlBuilder<T : Any> { - /** - * The priority of this renderer compared to other renderers - */ - val priority: Int - - /** - * The type of the content served by this renderer - */ - val type: KClass<T> - - suspend fun TagConsumer<*>.render(obj: T) - - companion object { - const val HTML_CONVERTER_TYPE = "dataforge.htmlBuilder" - } -} - -object DefaultHtmlBuilder : HtmlBuilder<Any> { - override val priority: Int = Int.MAX_VALUE - override val type: KClass<Any> = Any::class - - override suspend fun TagConsumer<*>.render(obj: Any) { - p { +obj.toString() } - } -} \ No newline at end of file diff --git a/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/OutputManager.kt b/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/OutputManager.kt index a8b1697d..e606c9b7 100644 --- a/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/OutputManager.kt +++ b/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/OutputManager.kt @@ -11,7 +11,7 @@ import kotlin.reflect.KClass /** * A manager for outputs */ -interface OutputManager { +public interface OutputManager { /** * Get an output specialized for given type, name and stage. @@ -19,7 +19,7 @@ interface OutputManager { * @param name represents the name inside the node. * @param meta configuration for [Renderer] (not for rendered object) */ - operator fun <T : Any> get( + public fun <T : Any> getOutputContainer( type: KClass<out T>, name: Name, stage: Name = Name.EMPTY, @@ -30,53 +30,46 @@ interface OutputManager { /** * Get an output manager for a context */ -val Context.output: OutputManager get() = plugins.get() ?: ConsoleOutputManager() +public val Context.output: OutputManager get() = plugins.get() ?: ConsoleOutputManager() /** * Get an output with given [name], [stage] and reified content type */ -inline operator fun <reified T : Any> OutputManager.get( +public inline fun <reified T : Any> OutputManager.getOutputContainer( name: Name, stage: Name = Name.EMPTY, meta: Meta = Meta.EMPTY ): Renderer<T> { - return get(T::class, name, stage, meta) + return getOutputContainer(T::class, name, stage, meta) } /** * Directly render an object using the most suitable renderer */ -fun OutputManager.render(obj: Any, name: Name, stage: Name = Name.EMPTY, meta: Meta = Meta.EMPTY) = - get(obj::class, name, stage).render(obj, meta) +public fun OutputManager.render(obj: Any, name: Name, stage: Name = Name.EMPTY, meta: Meta = Meta.EMPTY): Unit = + getOutputContainer(obj::class, name, stage).render(obj, meta) /** * System console output. * The [CONSOLE_RENDERER] is used when no other [OutputManager] is provided. */ -val CONSOLE_RENDERER: Renderer<Any> = object : Renderer<Any> { - override fun render(obj: Any, meta: Meta) { - println(obj) - } +public val CONSOLE_RENDERER: Renderer<Any> = Renderer { obj, meta -> println(obj) } - override val context: Context get() = Global - -} - -class ConsoleOutputManager : AbstractPlugin(), OutputManager { +public class ConsoleOutputManager : AbstractPlugin(), OutputManager { override val tag: PluginTag get() = ConsoleOutputManager.tag - override fun <T : Any> get(type: KClass<out T>, name: Name, stage: Name, meta: Meta): Renderer<T> = CONSOLE_RENDERER + override fun <T : Any> getOutputContainer(type: KClass<out T>, name: Name, stage: Name, meta: Meta): Renderer<T> = CONSOLE_RENDERER - companion object : PluginFactory<ConsoleOutputManager> { - override val tag = PluginTag("output.console", group = DATAFORGE_GROUP) + public companion object : PluginFactory<ConsoleOutputManager> { + override val tag: PluginTag = PluginTag("output.console", group = DATAFORGE_GROUP) - override val type = ConsoleOutputManager::class + override val type: KClass<ConsoleOutputManager> = ConsoleOutputManager::class - override fun invoke(meta: Meta, context: Context) = ConsoleOutputManager() + override fun invoke(meta: Meta, context: Context): ConsoleOutputManager = ConsoleOutputManager() } } /** * A dispatcher for output tasks. */ -expect val Dispatchers.Output: CoroutineDispatcher \ No newline at end of file +public expect val Dispatchers.Output: CoroutineDispatcher \ No newline at end of file diff --git a/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/Renderer.kt b/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/Renderer.kt index 9f8009d1..ebcb03ba 100644 --- a/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/Renderer.kt +++ b/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/Renderer.kt @@ -10,12 +10,12 @@ import hep.dataforge.meta.Meta * based on its configuration and provided meta * */ -interface Renderer<in T : Any> : ContextAware { +public fun interface Renderer<in T : Any> { /** * Render specific object with configuration. * * By convention actual render is called in asynchronous mode, so this method should never * block execution */ - fun render(obj: T, meta: Meta = Meta.EMPTY) + public fun render(obj: T, meta: Meta) } diff --git a/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/TextRenderer.kt b/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/TextRenderer.kt index cc9d24f3..235cdab2 100644 --- a/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/TextRenderer.kt +++ b/dataforge-output/src/commonMain/kotlin/hep/dataforge/output/TextRenderer.kt @@ -7,11 +7,47 @@ import hep.dataforge.provider.Type import hep.dataforge.provider.top import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import kotlinx.io.Output -import kotlinx.io.text.writeUtf8String import kotlin.reflect.KClass +import kotlin.reflect.KType -class TextRenderer(override val context: Context, private val output: Output) : Renderer<Any> { + +/** + * A text or binary renderer based on [Output] + */ +@Type(TEXT_RENDERER_TYPE) +@Deprecated("Bad design") +public interface TextFormat { + /** + * The priority of this renderer compared to other renderers + */ + public val priority: Int + /** + * The type of the content served by this renderer + */ + public val type: KClass<*> + + public suspend fun Appendable.render(obj: Any) + + public companion object { + public const val TEXT_RENDERER_TYPE: String = "dataforge.textRenderer" + } +} + +@Deprecated("Bad design") +public object DefaultTextFormat : TextFormat { + override val priority: Int = Int.MAX_VALUE + override val type: KClass<*> = Any::class + + override suspend fun Appendable.render(obj: Any) { + append(obj.toString() + "\n") + } +} + +/** + * A text-based renderer + */ +@Deprecated("Bad design") +public class TextRenderer(override val context: Context, private val output: Appendable) : Renderer<Any> { private val cache = HashMap<KClass<*>, TextFormat>() /** @@ -39,34 +75,4 @@ class TextRenderer(override val context: Context, private val output: Output) : format.run { output.render(obj) } } } -} - -/** - * A text or binary renderer based on [Output] - */ -@Type(TEXT_RENDERER_TYPE) -interface TextFormat { - /** - * The priority of this renderer compared to other renderers - */ - val priority: Int - /** - * The type of the content served by this renderer - */ - val type: KClass<*> - - suspend fun Output.render(obj: Any) - - companion object { - const val TEXT_RENDERER_TYPE = "dataforge.textRenderer" - } -} - -object DefaultTextFormat : TextFormat { - override val priority: Int = Int.MAX_VALUE - override val type: KClass<*> = Any::class - - override suspend fun Output.render(obj: Any) { - writeUtf8String(obj.toString() + "\n") - } } \ No newline at end of file diff --git a/dataforge-output/src/jsMain/kotlin/hep/dataforge/output/outputJS.kt b/dataforge-output/src/jsMain/kotlin/hep/dataforge/output/outputJS.kt index 18a71f07..be973122 100644 --- a/dataforge-output/src/jsMain/kotlin/hep/dataforge/output/outputJS.kt +++ b/dataforge-output/src/jsMain/kotlin/hep/dataforge/output/outputJS.kt @@ -4,4 +4,4 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers -actual val Dispatchers.Output: CoroutineDispatcher get() = Dispatchers.Default \ No newline at end of file +public actual val Dispatchers.Output: CoroutineDispatcher get() = Default \ No newline at end of file diff --git a/dataforge-output/src/jvmMain/kotlin/hep/dataforge/output/outputJVM.kt b/dataforge-output/src/jvmMain/kotlin/hep/dataforge/output/outputJVM.kt index ea7c416c..24c789fd 100644 --- a/dataforge-output/src/jvmMain/kotlin/hep/dataforge/output/outputJVM.kt +++ b/dataforge-output/src/jvmMain/kotlin/hep/dataforge/output/outputJVM.kt @@ -1,5 +1,6 @@ package hep.dataforge.output +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers -actual val Dispatchers.Output get() = Dispatchers.IO \ No newline at end of file +public actual val Dispatchers.Output: CoroutineDispatcher get() = IO \ No newline at end of file diff --git a/dataforge-output/src/nativeMain/kotlin/hep/dataforge/output/outputNative.kt b/dataforge-output/src/nativeMain/kotlin/hep/dataforge/output/outputNative.kt new file mode 100644 index 00000000..32eb85f5 --- /dev/null +++ b/dataforge-output/src/nativeMain/kotlin/hep/dataforge/output/outputNative.kt @@ -0,0 +1,6 @@ +package hep.dataforge.output + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers + +public actual val Dispatchers.Output: CoroutineDispatcher get() = Dispatchers.Default \ No newline at end of file diff --git a/dataforge-scripting/api/dataforge-scripting.api b/dataforge-scripting/api/dataforge-scripting.api new file mode 100644 index 00000000..b41aa156 --- /dev/null +++ b/dataforge-scripting/api/dataforge-scripting.api @@ -0,0 +1,6 @@ +public final class hep/dataforge/scripting/Builders { + public static final field INSTANCE Lhep/dataforge/scripting/Builders; + public final fun buildWorkspace (Ljava/io/File;)Lhep/dataforge/workspace/Workspace; + public final fun buildWorkspace (Ljava/lang/String;)Lhep/dataforge/workspace/Workspace; +} + diff --git a/dataforge-scripting/build.gradle.kts b/dataforge-scripting/build.gradle.kts index c848c1b1..cb16b66e 100644 --- a/dataforge-scripting/build.gradle.kts +++ b/dataforge-scripting/build.gradle.kts @@ -1,23 +1,22 @@ plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") } kotlin { - jvm() sourceSets { - val commonMain by getting { + commonMain { dependencies { api(project(":dataforge-workspace")) implementation(kotlin("scripting-common")) } } - val jvmMain by getting { + jvmMain{ dependencies { - implementation(kotlin("scripting-jvm-host-embeddable")) + implementation(kotlin("scripting-jvm-host")) implementation(kotlin("scripting-jvm")) } } - val jvmTest by getting { + jvmTest { dependencies { implementation("ch.qos.logback:logback-classic:1.2.3") } diff --git a/dataforge-scripting/src/commonMain/kotlin/hep/dataforge/scripting/Placeholder.kt b/dataforge-scripting/src/commonMain/kotlin/hep/dataforge/scripting/Placeholder.kt deleted file mode 100644 index a09e35c1..00000000 --- a/dataforge-scripting/src/commonMain/kotlin/hep/dataforge/scripting/Placeholder.kt +++ /dev/null @@ -1,4 +0,0 @@ -package hep.dataforge.scripting - -internal object Placeholder { -} \ No newline at end of file diff --git a/dataforge-scripting/src/jvmMain/kotlin/hep/dataforge/scripting/Builders.kt b/dataforge-scripting/src/jvmMain/kotlin/hep/dataforge/scripting/Builders.kt index 2df5a183..e8b1d378 100644 --- a/dataforge-scripting/src/jvmMain/kotlin/hep/dataforge/scripting/Builders.kt +++ b/dataforge-scripting/src/jvmMain/kotlin/hep/dataforge/scripting/Builders.kt @@ -13,15 +13,18 @@ import kotlin.script.experimental.jvm.dependenciesFromCurrentContext import kotlin.script.experimental.jvm.jvm import kotlin.script.experimental.jvmhost.BasicJvmScriptingHost -object Builders { +public object Builders { - fun buildWorkspace(source: SourceCode, context: Context = Global): Workspace { + private fun buildWorkspace(source: SourceCode, context: Context = Global): Workspace { val builder = SimpleWorkspaceBuilder(context) val workspaceScriptConfiguration = ScriptCompilationConfiguration { - baseClass(Any::class) +// baseClass(Any::class) implicitReceivers(WorkspaceBuilder::class) - defaultImports("hep.dataforge.workspace.*") + defaultImports( + "hep.dataforge.meta.*", + "hep.dataforge.workspace.*" + ) jvm { dependenciesFromCurrentContext(wholeClasspath = true) } @@ -49,7 +52,7 @@ object Builders { return builder.build() } - fun buildWorkspace(file: File): Workspace = buildWorkspace(file.toScriptSource()) + public fun buildWorkspace(file: File): Workspace = buildWorkspace(file.toScriptSource()) - fun buildWorkspace(string: String): Workspace = buildWorkspace(string.toScriptSource()) + public fun buildWorkspace(string: String): Workspace = buildWorkspace(string.toScriptSource()) } \ No newline at end of file diff --git a/dataforge-tables/api/dataforge-tables.api b/dataforge-tables/api/dataforge-tables.api new file mode 100644 index 00000000..e037773a --- /dev/null +++ b/dataforge-tables/api/dataforge-tables.api @@ -0,0 +1,302 @@ +public final class hep/dataforge/tables/CachedTransformationColumn : hep/dataforge/tables/Column { + public fun <init> (Lhep/dataforge/tables/Table;Lkotlin/reflect/KClass;Ljava/lang/String;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function1;)V + public fun get (I)Ljava/lang/Object; + public final fun getMapper ()Lkotlin/jvm/functions/Function1; + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getName ()Ljava/lang/String; + public fun getSize ()I + public final fun getTable ()Lhep/dataforge/tables/Table; + public fun getType ()Lkotlin/reflect/KClass; +} + +public final class hep/dataforge/tables/CastColumn : hep/dataforge/tables/Column { + public fun <init> (Lhep/dataforge/tables/Column;Lkotlin/reflect/KClass;)V + public fun get (I)Ljava/lang/Object; + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getName ()Ljava/lang/String; + public final fun getOrigin ()Lhep/dataforge/tables/Column; + public fun getSize ()I + public fun getType ()Lkotlin/reflect/KClass; +} + +public final class hep/dataforge/tables/CastColumnKt { + public static final fun cast (Lhep/dataforge/tables/Column;Lkotlin/reflect/KClass;)Lhep/dataforge/tables/Column; + public static final fun get (Ljava/util/Collection;Lhep/dataforge/tables/ColumnHeader;)Lhep/dataforge/tables/Column; +} + +public abstract interface class hep/dataforge/tables/Column : hep/dataforge/tables/ColumnHeader { + public abstract fun get (I)Ljava/lang/Object; + public abstract fun getSize ()I +} + +public final class hep/dataforge/tables/ColumnDef : hep/dataforge/tables/ColumnHeader { + public fun <init> (Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Lkotlin/reflect/KClass; + public final fun component3 ()Lhep/dataforge/meta/Meta; + public final fun copy (Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;)Lhep/dataforge/tables/ColumnDef; + public static synthetic fun copy$default (Lhep/dataforge/tables/ColumnDef;Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/tables/ColumnDef; + public fun equals (Ljava/lang/Object;)Z + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getName ()Ljava/lang/String; + public fun getType ()Lkotlin/reflect/KClass; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public abstract interface class hep/dataforge/tables/ColumnHeader { + public abstract fun getMeta ()Lhep/dataforge/meta/Meta; + public abstract fun getName ()Ljava/lang/String; + public abstract fun getType ()Lkotlin/reflect/KClass; +} + +public final class hep/dataforge/tables/ColumnHeaderKt { + public static final fun getTextWidth (Lhep/dataforge/tables/ColumnHeader;)I + public static final fun getValueType (Lhep/dataforge/tables/ColumnHeader;)Lhep/dataforge/values/ValueType; +} + +public final class hep/dataforge/tables/ColumnProperty : kotlin/properties/ReadOnlyProperty { + public fun <init> (Lhep/dataforge/tables/Table;Lkotlin/reflect/KClass;)V + public final fun getTable ()Lhep/dataforge/tables/Table; + public final fun getType ()Lkotlin/reflect/KClass; + public fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Lhep/dataforge/tables/Column; + public synthetic fun getValue (Ljava/lang/Object;Lkotlin/reflect/KProperty;)Ljava/lang/Object; +} + +public class hep/dataforge/tables/ColumnScheme : hep/dataforge/meta/Scheme { + public static final field Companion Lhep/dataforge/tables/ColumnScheme$Companion; + public fun <init> ()V + public final fun getTitle ()Ljava/lang/String; + public final fun setTitle (Ljava/lang/String;)V +} + +public final class hep/dataforge/tables/ColumnScheme$Companion : hep/dataforge/meta/SchemeSpec { +} + +public final class hep/dataforge/tables/ColumnTable : hep/dataforge/tables/Table { + public fun <init> (Ljava/util/Collection;)V + public fun getColumns ()Ljava/util/Collection; + public fun getHeader ()Ljava/util/List; + public fun getRows ()Ljava/util/List; + public fun getValue (ILjava/lang/String;)Ljava/lang/Object; + public fun rowFlow ()Lkotlinx/coroutines/flow/Flow; +} + +public final class hep/dataforge/tables/IntColumn : hep/dataforge/tables/Column { + public static final field Companion Lhep/dataforge/tables/IntColumn$Companion; + public fun <init> (Ljava/lang/String;[ILhep/dataforge/meta/Meta;)V + public synthetic fun <init> (Ljava/lang/String;[ILhep/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun equals (Ljava/lang/Object;)Z + public fun get (I)Ljava/lang/Integer; + public synthetic fun get (I)Ljava/lang/Object; + public final fun getData ()[I + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getName ()Ljava/lang/String; + public fun getSize ()I + public fun getType ()Lkotlin/reflect/KClass; + public fun hashCode ()I +} + +public final class hep/dataforge/tables/IntColumn$Companion { +} + +public final class hep/dataforge/tables/ListColumn : hep/dataforge/tables/Column { + public static final field Companion Lhep/dataforge/tables/ListColumn$Companion; + public fun <init> (Ljava/lang/String;Ljava/util/List;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;)V + public fun get (I)Ljava/lang/Object; + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getName ()Ljava/lang/String; + public fun getSize ()I + public fun getType ()Lkotlin/reflect/KClass; +} + +public final class hep/dataforge/tables/ListColumn$Companion { +} + +public final class hep/dataforge/tables/MapRow : hep/dataforge/tables/Row { + public static final synthetic fun box-impl (Ljava/util/Map;)Lhep/dataforge/tables/MapRow; + public static fun constructor-impl (Ljava/util/Map;)Ljava/util/Map; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl (Ljava/util/Map;Ljava/lang/Object;)Z + public static final fun equals-impl0 (Ljava/util/Map;Ljava/util/Map;)Z + public fun getValue (Ljava/lang/String;)Ljava/lang/Object; + public static fun getValue-impl (Ljava/util/Map;Ljava/lang/String;)Ljava/lang/Object; + public fun hashCode ()I + public static fun hashCode-impl (Ljava/util/Map;)I + public fun toString ()Ljava/lang/String; + public static fun toString-impl (Ljava/util/Map;)Ljava/lang/String; + public final synthetic fun unbox-impl ()Ljava/util/Map; +} + +public final class hep/dataforge/tables/MutableColumnTable : hep/dataforge/tables/Table { + public fun <init> (I)V + public final fun add (Lhep/dataforge/tables/Column;)V + public synthetic fun getColumns ()Ljava/util/Collection; + public fun getColumns ()Ljava/util/List; + public fun getHeader ()Ljava/util/List; + public fun getRows ()Ljava/util/List; + public final fun getSize ()I + public fun getValue (ILjava/lang/String;)Ljava/lang/Object; + public final fun insert (ILhep/dataforge/tables/Column;)V + public fun rowFlow ()Lkotlinx/coroutines/flow/Flow; +} + +public final class hep/dataforge/tables/MutableTable : hep/dataforge/tables/RowTable { + public fun <init> (Ljava/util/List;Ljava/util/List;)V + public final fun column (Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;)Lhep/dataforge/tables/ColumnHeader; + public fun getHeader ()Ljava/util/List; + public fun getRows ()Ljava/util/List; + public final fun row (Ljava/util/Map;)Lhep/dataforge/tables/Row; + public final fun row ([Lkotlin/Pair;)Lhep/dataforge/tables/Row; +} + +public final class hep/dataforge/tables/MutableTableKt { + public static final fun edit (Lhep/dataforge/tables/Table;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/tables/Table; + public static final fun row (Lhep/dataforge/tables/MutableTable;[Lkotlin/Pair;)Lhep/dataforge/tables/Row; +} + +public final class hep/dataforge/tables/RealColumn : hep/dataforge/tables/Column { + public static final field Companion Lhep/dataforge/tables/RealColumn$Companion; + public fun <init> (Ljava/lang/String;[DLhep/dataforge/meta/Meta;)V + public synthetic fun <init> (Ljava/lang/String;[DLhep/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun equals (Ljava/lang/Object;)Z + public fun get (I)Ljava/lang/Double; + public synthetic fun get (I)Ljava/lang/Object; + public final fun getData ()[D + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getName ()Ljava/lang/String; + public fun getSize ()I + public fun getType ()Lkotlin/reflect/KClass; + public fun hashCode ()I +} + +public final class hep/dataforge/tables/RealColumn$Companion { +} + +public abstract interface class hep/dataforge/tables/Row { + public abstract fun getValue (Ljava/lang/String;)Ljava/lang/Object; +} + +public class hep/dataforge/tables/RowTable : hep/dataforge/tables/Table { + public fun <init> (Ljava/util/List;Ljava/util/List;)V + public synthetic fun getColumns ()Ljava/util/Collection; + public fun getColumns ()Ljava/util/List; + public fun getHeader ()Ljava/util/List; + public fun getRows ()Ljava/util/List; + public fun getValue (ILjava/lang/String;)Ljava/lang/Object; + public fun rowFlow ()Lkotlinx/coroutines/flow/Flow; +} + +public final class hep/dataforge/tables/RowTableKt { + public static final fun collect (Lhep/dataforge/tables/Rows;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public abstract interface class hep/dataforge/tables/Rows { + public abstract fun getHeader ()Ljava/util/List; + public abstract fun rowFlow ()Lkotlinx/coroutines/flow/Flow; +} + +public final class hep/dataforge/tables/SimpleColumnHeader : hep/dataforge/tables/ColumnHeader { + public fun <init> (Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Lkotlin/reflect/KClass; + public final fun component3 ()Lhep/dataforge/meta/Meta; + public final fun copy (Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;)Lhep/dataforge/tables/SimpleColumnHeader; + public static synthetic fun copy$default (Lhep/dataforge/tables/SimpleColumnHeader;Ljava/lang/String;Lkotlin/reflect/KClass;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/tables/SimpleColumnHeader; + public fun equals (Ljava/lang/Object;)Z + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getName ()Ljava/lang/String; + public fun getType ()Lkotlin/reflect/KClass; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public abstract interface class hep/dataforge/tables/Table : hep/dataforge/tables/Rows { + public static final field Companion Lhep/dataforge/tables/Table$Companion; + public abstract fun getColumns ()Ljava/util/Collection; + public abstract fun getHeader ()Ljava/util/List; + public abstract fun getRows ()Ljava/util/List; + public abstract fun getValue (ILjava/lang/String;)Ljava/lang/Object; + public abstract fun rowFlow ()Lkotlinx/coroutines/flow/Flow; +} + +public final class hep/dataforge/tables/Table$Companion { + public final fun invoke (Lkotlin/jvm/functions/Function1;)Lhep/dataforge/tables/Table; +} + +public final class hep/dataforge/tables/Table$DefaultImpls { + public static fun getHeader (Lhep/dataforge/tables/Table;)Ljava/util/List; + public static fun rowFlow (Lhep/dataforge/tables/Table;)Lkotlinx/coroutines/flow/Flow; +} + +public final class hep/dataforge/tables/TableKt { + public static final fun get (Lhep/dataforge/tables/Row;Lhep/dataforge/tables/ColumnHeader;)Ljava/lang/Object; + public static final fun get (Lhep/dataforge/tables/Table;ILhep/dataforge/tables/ColumnHeader;)Ljava/lang/Object; + public static final fun get (Ljava/util/Collection;Ljava/lang/String;)Lhep/dataforge/tables/Column; + public static final fun getIndices (Lhep/dataforge/tables/Column;)Lkotlin/ranges/IntRange; + public static final fun getValue (Lhep/dataforge/tables/Row;Ljava/lang/String;Lkotlin/reflect/KClass;)Ljava/lang/Object; + public static final fun getValue (Lhep/dataforge/tables/Table;ILjava/lang/String;Lkotlin/reflect/KClass;)Ljava/lang/Object; + public static final fun iterator (Lhep/dataforge/tables/Column;)Ljava/util/Iterator; +} + +public final class hep/dataforge/tables/TransformationColumn : hep/dataforge/tables/Column { + public fun <init> (Lhep/dataforge/tables/Table;Lkotlin/reflect/KClass;Ljava/lang/String;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function1;)V + public fun get (I)Ljava/lang/Object; + public final fun getMapper ()Lkotlin/jvm/functions/Function1; + public fun getMeta ()Lhep/dataforge/meta/Meta; + public fun getName ()Ljava/lang/String; + public fun getSize ()I + public final fun getTable ()Lhep/dataforge/tables/Table; + public fun getType ()Lkotlin/reflect/KClass; +} + +public final class hep/dataforge/tables/TransformationColumnKt { + public static final fun mapRowsToDouble (Lhep/dataforge/tables/Table;Ljava/lang/String;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/tables/RealColumn; + public static synthetic fun mapRowsToDouble$default (Lhep/dataforge/tables/Table;Ljava/lang/String;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/tables/RealColumn; + public static final fun mapRowsToInt (Lhep/dataforge/tables/Table;Ljava/lang/String;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/tables/IntColumn; + public static synthetic fun mapRowsToInt$default (Lhep/dataforge/tables/Table;Ljava/lang/String;Lhep/dataforge/meta/Meta;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/tables/IntColumn; +} + +public final class hep/dataforge/tables/ValueColumnScheme : hep/dataforge/tables/ColumnScheme { + public fun <init> ()V + public final fun getValueType ()Lhep/dataforge/values/ValueType; + public final fun setValueType (Lhep/dataforge/values/ValueType;)V +} + +public final class hep/dataforge/tables/io/TextRows : hep/dataforge/tables/Rows { + public static final field Companion Lhep/dataforge/tables/io/TextRows$Companion; + public fun <init> (Ljava/util/List;Lkotlinx/io/Binary;)V + public fun getHeader ()Ljava/util/List; + public final fun indexFlow ()Lkotlinx/coroutines/flow/Flow; + public fun rowFlow ()Lkotlinx/coroutines/flow/Flow; +} + +public final class hep/dataforge/tables/io/TextRows$Companion { +} + +public final class hep/dataforge/tables/io/TextRowsKt { + public static final fun buildRowIndex (Lhep/dataforge/tables/io/TextRows;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static final fun writeRows (Lkotlinx/io/Output;Lhep/dataforge/tables/Rows;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class hep/dataforge/tables/io/TextTable : hep/dataforge/tables/Table { + public static final field Companion Lhep/dataforge/tables/io/TextTable$Companion; + public fun <init> (Ljava/util/List;Lkotlinx/io/Binary;Ljava/util/List;)V + public fun getColumns ()Ljava/util/Collection; + public fun getHeader ()Ljava/util/List; + public final fun getIndex ()Ljava/util/List; + public fun getRows ()Ljava/util/List; + public fun getValue (ILjava/lang/String;)Lhep/dataforge/values/Value; + public synthetic fun getValue (ILjava/lang/String;)Ljava/lang/Object; + public fun rowFlow ()Lkotlinx/coroutines/flow/Flow; +} + +public final class hep/dataforge/tables/io/TextTable$Companion { + public final fun invoke (Ljava/util/List;Lkotlinx/io/Binary;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class hep/dataforge/tables/io/TextTableEnvelopeKt { + public static final fun readEnvelope (Lhep/dataforge/tables/io/TextRows$Companion;Lhep/dataforge/io/Envelope;)Lhep/dataforge/tables/io/TextRows; + public static final fun wrap (Lhep/dataforge/tables/Table;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + diff --git a/dataforge-tables/build.gradle.kts b/dataforge-tables/build.gradle.kts index 6c0a1e53..e88f70d1 100644 --- a/dataforge-tables/build.gradle.kts +++ b/dataforge-tables/build.gradle.kts @@ -1,5 +1,6 @@ plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") + id("ru.mipt.npm.native") } kotlin { diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnDef.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnDef.kt index 2df51d41..2dd2e85b 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnDef.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnDef.kt @@ -3,7 +3,7 @@ package hep.dataforge.tables import hep.dataforge.meta.Meta import kotlin.reflect.KClass -data class ColumnDef<out T : Any>( +public data class ColumnDef<out T : Any>( override val name: String, override val type: KClass<out T>, override val meta: Meta diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnHeader.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnHeader.kt index 2023d11b..a226de26 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnHeader.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnHeader.kt @@ -8,25 +8,25 @@ import hep.dataforge.values.Value import hep.dataforge.values.ValueType import kotlin.reflect.KClass -typealias TableHeader<C> = List<ColumnHeader<C>> +public typealias TableHeader<C> = List<ColumnHeader<C>> -typealias ValueTableHeader = List<ColumnHeader<Value>> +public typealias ValueTableHeader = List<ColumnHeader<Value>> -interface ColumnHeader<out T : Any> { - val name: String - val type: KClass<out T> - val meta: Meta +public interface ColumnHeader<out T : Any> { + public val name: String + public val type: KClass<out T> + public val meta: Meta } -data class SimpleColumnHeader<T : Any>( +public data class SimpleColumnHeader<T : Any>( override val name: String, override val type: KClass<out T>, override val meta: Meta ) : ColumnHeader<T> -val ColumnHeader<Value>.valueType: ValueType? get() = meta["valueType"].string?.let { ValueType.valueOf(it) } +public val ColumnHeader<Value>.valueType: ValueType? get() = meta["valueType"].string?.let { ValueType.valueOf(it) } -val ColumnHeader<Value>.textWidth: Int +public val ColumnHeader<Value>.textWidth: Int get() = meta["columnWidth"].int ?: when (valueType) { ValueType.NUMBER -> 8 ValueType.STRING -> 16 diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnScheme.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnScheme.kt index c71ee53f..17968a82 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnScheme.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnScheme.kt @@ -6,12 +6,12 @@ import hep.dataforge.meta.enum import hep.dataforge.meta.string import hep.dataforge.values.ValueType -open class ColumnScheme : Scheme() { - var title by string() +public open class ColumnScheme : Scheme() { + public var title: String? by string() - companion object : SchemeSpec<ColumnScheme>(::ColumnScheme) + public companion object : SchemeSpec<ColumnScheme>(::ColumnScheme) } -class ValueColumnScheme : ColumnScheme() { - var valueType by enum(ValueType.STRING) +public class ValueColumnScheme : ColumnScheme() { + public var valueType: ValueType by enum(ValueType.STRING) } \ No newline at end of file diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnTable.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnTable.kt index db80b6fa..e79ebd08 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnTable.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ColumnTable.kt @@ -3,7 +3,7 @@ package hep.dataforge.tables /** * @param T bottom type for all columns in the table */ -class ColumnTable<T : Any>(override val columns: Collection<Column<T>>) : Table<T> { +public class ColumnTable<T : Any>(override val columns: Collection<Column<T>>) : Table<T> { private val rowsNum = columns.first().size init { diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ListColumn.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ListColumn.kt index fc7f03ea..7b0549fa 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ListColumn.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/ListColumn.kt @@ -3,7 +3,7 @@ package hep.dataforge.tables import hep.dataforge.meta.Meta import kotlin.reflect.KClass -class ListColumn<T : Any>( +public class ListColumn<T : Any>( override val name: String, private val data: List<T?>, override val type: KClass<out T>, @@ -13,14 +13,14 @@ class ListColumn<T : Any>( override fun get(index: Int): T? = data[index] - companion object { - inline operator fun <reified T : Any> invoke( + public companion object { + public inline operator fun <reified T : Any> invoke( name: String, def: ColumnScheme, data: List<T?> ): ListColumn<T> = ListColumn(name, data, T::class, def.toMeta()) - inline operator fun <reified T : Any> invoke( + public inline operator fun <reified T : Any> invoke( name: String, def: ColumnScheme, size: Int, @@ -29,7 +29,7 @@ class ListColumn<T : Any>( } } -inline fun <T : Any, reified R : Any> Column<T>.map(meta: Meta = this.meta, noinline block: (T?) -> R): Column<R> { +public inline fun <T : Any, reified R : Any> Column<T>.map(meta: Meta = this.meta, noinline block: (T?) -> R): Column<R> { val data = List(size) { block(get(it)) } return ListColumn(name, data, R::class, meta) } \ No newline at end of file diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableColumnTable.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableColumnTable.kt index 4b93a13d..eb69d7e7 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableColumnTable.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableColumnTable.kt @@ -3,7 +3,7 @@ package hep.dataforge.tables /** * Mutable table with a fixed size, but dynamic columns */ -class MutableColumnTable<C: Any>(val size: Int) : Table<C> { +public class MutableColumnTable<C: Any>(public val size: Int) : Table<C> { private val _columns = ArrayList<Column<C>>() override val columns: List<Column<C>> get() = _columns @@ -16,7 +16,7 @@ class MutableColumnTable<C: Any>(val size: Int) : Table<C> { /** * Add a fixed column to the end of the table */ - fun add(column: Column<C>) { + public fun add(column: Column<C>) { require(column.size == this.size) { "Required column size $size, but found ${column.size}" } _columns.add(column) } @@ -24,7 +24,7 @@ class MutableColumnTable<C: Any>(val size: Int) : Table<C> { /** * Insert a column at [index] */ - fun insert(index: Int, column: Column<C>) { + public fun insert(index: Int, column: Column<C>) { require(column.size == this.size) { "Required column size $size, but found ${column.size}" } _columns.add(index, column) } diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableTable.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableTable.kt index a59108a6..f4070146 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableTable.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/MutableTable.kt @@ -1,40 +1,41 @@ package hep.dataforge.tables import hep.dataforge.meta.Meta +import hep.dataforge.meta.invoke import hep.dataforge.values.Value import kotlin.reflect.KClass -class MutableTable<C : Any>( +public class MutableTable<C : Any>( override val rows: MutableList<Row<C>>, override val header: MutableList<ColumnHeader<C>> ) : RowTable<C>(rows, header) { - fun <R : C> column(name: String, type: KClass<out R>, meta: Meta): ColumnHeader<R> { + public fun <R : C> column(name: String, type: KClass<out R>, meta: Meta): ColumnHeader<R> { val column = SimpleColumnHeader(name, type, meta) header.add(column) return column } - inline fun <reified T : C> column( + public inline fun <reified T : C> column( name: String, noinline columnMetaBuilder: ColumnScheme.() -> Unit = {} ): ColumnHeader<T> { return column(name, T::class, ColumnScheme(columnMetaBuilder).toMeta()) } - fun row(map: Map<String, C?>): Row<C> { + public fun row(map: Map<String, C?>): Row<C> { val row = MapRow(map) rows.add(row) return row } - fun <T : C> row(vararg pairs: Pair<ColumnHeader<T>, T>): Row<C> = + public fun <T : C> row(vararg pairs: Pair<ColumnHeader<T>, T>): Row<C> = row(pairs.associate { it.first.name to it.second }) } -fun MutableTable<Value>.row(vararg pairs: Pair<ColumnHeader<Value>, Any?>): Row<Value> = +public fun MutableTable<Value>.row(vararg pairs: Pair<ColumnHeader<Value>, Any?>): Row<Value> = row(pairs.associate { it.first.name to Value.of(it.second) }) -fun <C : Any> Table<C>.edit(block: MutableTable<C>.() -> Unit): Table<C> { +public fun <C : Any> Table<C>.edit(block: MutableTable<C>.() -> Unit): Table<C> { return MutableTable(rows.toMutableList(), header.toMutableList()).apply(block) } \ No newline at end of file diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/RowTable.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/RowTable.kt index aa3449fb..9ea908cc 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/RowTable.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/RowTable.kt @@ -4,7 +4,7 @@ import hep.dataforge.meta.Meta import kotlinx.coroutines.flow.toList import kotlin.reflect.KClass -inline class MapRow<C : Any>(val values: Map<String, C?>) : Row<C> { +public inline class MapRow<C : Any>(private val values: Map<String, C?>) : Row<C> { override fun getValue(column: String): C? = values[column] } @@ -17,10 +17,10 @@ internal class RowTableColumn<C : Any, T : C>(val table: Table<C>, val header: C override fun get(index: Int): T? = table.rows[index].getValue(name, type) } -open class RowTable<C : Any>(override val rows: List<Row<C>>, override val header: List<ColumnHeader<C>>) : Table<C> { +public open class RowTable<C : Any>(override val rows: List<Row<C>>, override val header: List<ColumnHeader<C>>) : Table<C> { override fun getValue(row: Int, column: String): C? = rows[row].getValue(column) override val columns: List<Column<C>> get() = header.map { RowTableColumn(this, it) } } -suspend fun <C : Any> Rows<C>.collect(): Table<C> = this as? Table<C> ?: RowTable(rowFlow().toList(), header) \ No newline at end of file +public suspend fun <C : Any> Rows<C>.collect(): Table<C> = this as? Table<C> ?: RowTable(rowFlow().toList(), header) \ No newline at end of file diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/Table.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/Table.kt index 0197955d..72875a05 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/Table.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/Table.kt @@ -9,57 +9,57 @@ import kotlin.reflect.cast * Finite or infinite row set. Rows are produced in a lazy suspendable [Flow]. * Each row must contain at least all the fields mentioned in [header]. */ -interface Rows<out T : Any> { - val header: TableHeader<T> - fun rowFlow(): Flow<Row<T>> +public interface Rows<out T : Any> { + public val header: TableHeader<T> + public fun rowFlow(): Flow<Row<T>> } -interface Table<out T : Any> : Rows<T> { - fun getValue(row: Int, column: String): T? - val columns: Collection<Column<T>> +public interface Table<out T : Any> : Rows<T> { + public fun getValue(row: Int, column: String): T? + public val columns: Collection<Column<T>> override val header: TableHeader<T> get() = columns.toList() - val rows: List<Row<T>> + public val rows: List<Row<T>> override fun rowFlow(): Flow<Row<T>> = rows.asFlow() /** * Apply typed query to this table and return lazy [Flow] of resulting rows. The flow could be empty. */ //fun select(query: Any): Flow<Row> = error("Query of type ${query::class} is not supported by this table") - companion object { - inline operator fun <T : Any> invoke(block: MutableTable<T>.() -> Unit): Table<T> = + public companion object { + public inline operator fun <T : Any> invoke(block: MutableTable<T>.() -> Unit): Table<T> = MutableTable<T>(arrayListOf(), arrayListOf()).apply(block) } } -fun <C : Any, T : C> Table<C>.getValue(row: Int, column: String, type: KClass<out T>): T? = +public fun <C : Any, T : C> Table<C>.getValue(row: Int, column: String, type: KClass<out T>): T? = type.cast(getValue(row, column)) -operator fun <T : Any> Collection<Column<T>>.get(name: String): Column<T>? = find { it.name == name } +public operator fun <T : Any> Collection<Column<T>>.get(name: String): Column<T>? = find { it.name == name } -inline operator fun <C : Any, reified T : C> Table<C>.get(row: Int, column: String): T? = +public inline operator fun <C : Any, reified T : C> Table<C>.get(row: Int, column: String): T? = getValue(row, column, T::class) -operator fun <C : Any, T : C> Table<C>.get(row: Int, column: ColumnHeader<T>): T? = +public operator fun <C : Any, T : C> Table<C>.get(row: Int, column: ColumnHeader<T>): T? = getValue(row, column.name, column.type) -interface Column<out T : Any> : ColumnHeader<T> { - val size: Int - operator fun get(index: Int): T? +public interface Column<out T : Any> : ColumnHeader<T> { + public val size: Int + public operator fun get(index: Int): T? } -val Column<*>.indices get() = (0 until size) +public val Column<*>.indices: IntRange get() = (0 until size) -operator fun <T : Any> Column<T>.iterator() = iterator { +public operator fun <T : Any> Column<T>.iterator(): Iterator<T?> = iterator { for (i in indices) { yield(get(i)) } } -interface Row<out T : Any> { - fun getValue(column: String): T? +public interface Row<out T : Any> { + public fun getValue(column: String): T? } -fun <C : Any, T : C> Row<C>.getValue(column: String, type: KClass<out T>): T? = type.cast(getValue(column)) +public fun <C : Any, T : C> Row<C>.getValue(column: String, type: KClass<out T>): T? = type.cast(getValue(column)) -inline operator fun <reified T : Any> Row<T>.get(column: String): T? = T::class.cast(getValue(column)) -operator fun <C : Any, T : C> Row<C>.get(column: ColumnHeader<T>): T? = getValue(column.name, column.type) \ No newline at end of file +public inline operator fun <reified T : Any> Row<T>.get(column: String): T? = T::class.cast(getValue(column)) +public operator fun <C : Any, T : C> Row<C>.get(column: ColumnHeader<T>): T? = getValue(column.name, column.type) \ No newline at end of file diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/TransformationColumn.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/TransformationColumn.kt index 3c4fa2b4..83fdc06b 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/TransformationColumn.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/TransformationColumn.kt @@ -6,12 +6,12 @@ import kotlin.reflect.KClass /** * A virtual column obtained by transforming Given row to a single value */ -class TransformationColumn<T : Any, R : Any>( - val table: Table<T>, +public class TransformationColumn<T : Any, R : Any>( + public val table: Table<T>, override val type: KClass<out R>, override val name: String, override val meta: Meta, - val mapper: (Row<T>) -> R? + public val mapper: (Row<T>) -> R? ) : Column<R> { override val size: Int get() = table.rows.size @@ -23,12 +23,12 @@ class TransformationColumn<T : Any, R : Any>( * * Calls are not thread safe */ -class CachedTransformationColumn<T : Any, R : Any>( - val table: Table<T>, +public class CachedTransformationColumn<T : Any, R : Any>( + public val table: Table<T>, override val type: KClass<out R>, override val name: String, override val meta: Meta, - val mapper: (Row<T>) -> R? + public val mapper: (Row<T>) -> R? ) : Column<R> { override val size: Int get() = table.rows.size private val values: HashMap<Int, R?> = HashMap() @@ -38,7 +38,7 @@ class CachedTransformationColumn<T : Any, R : Any>( /** * Create a virtual column from a given column */ -inline fun <T : Any, reified R : Any> Table<T>.mapRows( +public inline fun <T : Any, reified R : Any> Table<T>.mapRows( name: String, meta: Meta = Meta.EMPTY, cache: Boolean = false, @@ -49,12 +49,12 @@ inline fun <T : Any, reified R : Any> Table<T>.mapRows( TransformationColumn(this, R::class, name, meta, mapper) } -fun <T : Any> Table<T>.mapRowsToDouble(name: String, meta: Meta = Meta.EMPTY, block: (Row<T>) -> Double): RealColumn { +public fun <T : Any> Table<T>.mapRowsToDouble(name: String, meta: Meta = Meta.EMPTY, block: (Row<T>) -> Double): RealColumn { val data = DoubleArray(rows.size) { block(rows[it]) } return RealColumn(name, data, meta) } -fun <T : Any> Table<T>.mapRowsToInt(name: String, meta: Meta = Meta.EMPTY, block: (Row<T>) -> Int): IntColumn { +public fun <T : Any> Table<T>.mapRowsToInt(name: String, meta: Meta = Meta.EMPTY, block: (Row<T>) -> Int): IntColumn { val data = IntArray(rows.size) { block(rows[it]) } return IntColumn(name, data, meta) } \ No newline at end of file diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/io/TextRows.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/io/TextRows.kt index 293031f8..31f5baaa 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/io/TextRows.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/io/TextRows.kt @@ -32,12 +32,12 @@ private fun readLine(header: ValueTableHeader, line: String): Row<Value> { * Finite or infinite [Rows] created from a fixed width text binary */ @ExperimentalIoApi -class TextRows(override val header: ValueTableHeader, val binary: Binary) : Rows<Value> { +public class TextRows(override val header: ValueTableHeader, private val binary: Binary) : Rows<Value> { /** * A flow of indexes of string start offsets ignoring empty strings */ - fun indexFlow(): Flow<Int> = binary.read { + public fun indexFlow(): Flow<Int> = binary.read { var counter: Int = 0 flow { val string = readUtf8StringUntilDelimiter('\n') @@ -59,23 +59,23 @@ class TextRows(override val header: ValueTableHeader, val binary: Binary) : Rows } } - companion object + public companion object } /** * Create a row offset index for [TextRows] */ @ExperimentalIoApi -suspend fun TextRows.buildRowIndex(): List<Int> = indexFlow().toList() +public suspend fun TextRows.buildRowIndex(): List<Int> = indexFlow().toList() /** * Finite table created from [RandomAccessBinary] with fixed width text table */ @ExperimentalIoApi -class TextTable( +public class TextTable( override val header: ValueTableHeader, - val binary: Binary, - val index: List<Int> + private val binary: Binary, + public val index: List<Int> ) : Table<Value> { override val columns: Collection<Column<Value>> get() = header.map { RowTableColumn(this, it) } @@ -96,8 +96,8 @@ class TextTable( return readAt(offset)[column] } - companion object { - suspend operator fun invoke(header: ValueTableHeader, binary: Binary): TextTable { + public companion object { + public suspend operator fun invoke(header: ValueTableHeader, binary: Binary): TextTable { val index = TextRows(header, binary).buildRowIndex() return TextTable(header, binary, index) } @@ -131,7 +131,7 @@ private fun Output.writeValue(value: Value, width: Int, left: Boolean = true) { /** * Write rows without header to the output */ -suspend fun Output.writeRows(rows: Rows<Value>) { +public suspend fun Output.writeRows(rows: Rows<Value>) { val widths: List<Int> = rows.header.map { it.textWidth } diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/io/textTableEnvelope.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/io/textTableEnvelope.kt index e634346c..4deb84e6 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/io/textTableEnvelope.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/io/textTableEnvelope.kt @@ -12,7 +12,7 @@ import kotlinx.io.asBinary @ExperimentalIoApi -suspend fun Table<Value>.wrap(): Envelope = Envelope { +public suspend fun Table<Value>.wrap(): Envelope = Envelope { meta { header.forEachIndexed { index, columnHeader -> set("column", index.toString(), Meta { @@ -32,9 +32,9 @@ suspend fun Table<Value>.wrap(): Envelope = Envelope { @DFExperimental @ExperimentalIoApi -fun TextRows.Companion.readEnvelope(envelope: Envelope): TextRows { +public fun TextRows.Companion.readEnvelope(envelope: Envelope): TextRows { val header = envelope.meta.getIndexed("column") - .entries.sortedBy { it.key.toInt() } + .entries.sortedBy { it.key?.toInt() } .map { (_, item) -> SimpleColumnHeader(item.node["name"].string!!, Value::class, item.node["meta"].node ?: Meta.EMPTY) } diff --git a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/numericColumns.kt b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/numericColumns.kt index 7f80b082..86868a22 100644 --- a/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/numericColumns.kt +++ b/dataforge-tables/src/commonMain/kotlin/hep/dataforge/tables/numericColumns.kt @@ -1,12 +1,13 @@ package hep.dataforge.tables import hep.dataforge.meta.Meta +import hep.dataforge.meta.invoke import kotlin.reflect.KClass -class RealColumn( +public class RealColumn( override val name: String, - val data: DoubleArray, + public val data: DoubleArray, override val meta: Meta = Meta.EMPTY ) : Column<Double> { override val type: KClass<out Double> get() = Double::class @@ -34,8 +35,8 @@ class RealColumn( return result } - companion object { - inline operator fun <reified T : Any> invoke( + public companion object { + public inline operator fun <reified T : Any> invoke( name: String, data: DoubleArray, noinline metaBuilder: ColumnScheme.() -> Unit @@ -43,9 +44,9 @@ class RealColumn( } } -class IntColumn( +public class IntColumn( override val name: String, - val data: IntArray, + public val data: IntArray, override val meta: Meta = Meta.EMPTY ) : Column<Int> { override val type: KClass<out Int> get() = Int::class @@ -73,8 +74,8 @@ class IntColumn( return result } - companion object { - inline operator fun <reified T : Any> invoke( + public companion object { + public inline operator fun <reified T : Any> invoke( name: String, data: IntArray, noinline metaBuilder: ColumnScheme.() -> Unit diff --git a/dataforge-workspace/api/dataforge-workspace.api b/dataforge-workspace/api/dataforge-workspace.api new file mode 100644 index 00000000..c410f094 --- /dev/null +++ b/dataforge-workspace/api/dataforge-workspace.api @@ -0,0 +1,273 @@ +public final class hep/dataforge/workspace/AllDataDependency : hep/dataforge/workspace/Dependency { + public fun <init> ()V + public fun <init> (Lhep/dataforge/names/Name;)V + public synthetic fun <init> (Lhep/dataforge/names/Name;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun apply (Lhep/dataforge/workspace/Workspace;)Lhep/dataforge/data/DataNode; + public synthetic fun toMeta ()Lhep/dataforge/meta/Meta; + public fun toMeta ()Lhep/dataforge/meta/MetaBuilder; +} + +public final class hep/dataforge/workspace/DataDependency : hep/dataforge/workspace/Dependency { + public fun <init> (Lhep/dataforge/data/DataFilter;Lhep/dataforge/names/Name;)V + public synthetic fun <init> (Lhep/dataforge/data/DataFilter;Lhep/dataforge/names/Name;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun apply (Lhep/dataforge/workspace/Workspace;)Lhep/dataforge/data/DataNode; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public abstract class hep/dataforge/workspace/Dependency : hep/dataforge/meta/MetaRepr { + public abstract fun apply (Lhep/dataforge/workspace/Workspace;)Lhep/dataforge/data/DataNode; +} + +public final class hep/dataforge/workspace/DirectTaskDependency : hep/dataforge/workspace/TaskDependency { + public static final field Companion Lhep/dataforge/workspace/DirectTaskDependency$Companion; + public fun <init> (Lhep/dataforge/workspace/Task;Lhep/dataforge/meta/Meta;Lhep/dataforge/names/Name;)V + public fun getName ()Lhep/dataforge/names/Name; + public final fun getTask ()Lhep/dataforge/workspace/Task; + public fun resolveTask (Lhep/dataforge/workspace/Workspace;)Lhep/dataforge/workspace/Task; +} + +public final class hep/dataforge/workspace/DirectTaskDependency$Companion { + public final fun getDIRECT_TASK_NAME ()Lhep/dataforge/names/Name; +} + +public final class hep/dataforge/workspace/EnvelopeDataKt { + public static final fun toData (Lhep/dataforge/io/Envelope;Lkotlin/reflect/KClass;Lhep/dataforge/io/IOFormat;)Lhep/dataforge/data/Data; + public static final fun toEnvelope (Lhep/dataforge/data/Data;Lhep/dataforge/io/IOFormat;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class hep/dataforge/workspace/FileDataKt { + public static final fun file (Lhep/dataforge/data/DataTreeBuilder;Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lkotlin/jvm/functions/Function2;)V + public static final fun readDataDirectory (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function2;)Lhep/dataforge/data/DataNode; + public static final fun readDataFile (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function2;)Lhep/dataforge/data/Data; + public static final fun writeDataDirectory (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/data/DataNode;Lhep/dataforge/io/IOFormat;Lhep/dataforge/io/EnvelopeFormat;Lhep/dataforge/io/MetaFormatFactory;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun writeDataDirectory$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/data/DataNode;Lhep/dataforge/io/IOFormat;Lhep/dataforge/io/EnvelopeFormat;Lhep/dataforge/io/MetaFormatFactory;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; + public static final fun writeZip (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/data/DataNode;Lhep/dataforge/io/IOFormat;Lhep/dataforge/io/EnvelopeFormat;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public static synthetic fun writeZip$default (Lhep/dataforge/io/IOPlugin;Ljava/nio/file/Path;Lhep/dataforge/data/DataNode;Lhep/dataforge/io/IOFormat;Lhep/dataforge/io/EnvelopeFormat;Lkotlin/coroutines/Continuation;ILjava/lang/Object;)Ljava/lang/Object; +} + +public final class hep/dataforge/workspace/GenericTask : hep/dataforge/workspace/Task { + public fun <init> (Lhep/dataforge/names/Name;Lkotlin/reflect/KClass;Lhep/dataforge/meta/descriptors/NodeDescriptor;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)V + public fun build (Lhep/dataforge/workspace/Workspace;Lhep/dataforge/meta/Meta;)Lhep/dataforge/workspace/TaskModel; + public synthetic fun getDescriptor ()Lhep/dataforge/meta/descriptors/ItemDescriptor; + public fun getDescriptor ()Lhep/dataforge/meta/descriptors/NodeDescriptor; + public fun getName ()Lhep/dataforge/names/Name; + public fun getType ()Lkotlin/reflect/KClass; + public fun isTerminal ()Z + public fun run (Lhep/dataforge/workspace/Workspace;Lhep/dataforge/workspace/TaskModel;)Lhep/dataforge/data/DataNode; + public fun validate (Lhep/dataforge/workspace/TaskModel;)V +} + +public final class hep/dataforge/workspace/SimpleWorkspace : hep/dataforge/workspace/Workspace { + public static final field Companion Lhep/dataforge/workspace/SimpleWorkspace$Companion; + public fun <init> (Lhep/dataforge/context/Context;Lhep/dataforge/data/DataNode;Ljava/util/Map;Ljava/util/Collection;)V + public fun content (Ljava/lang/String;)Ljava/util/Map; + public fun getContext ()Lhep/dataforge/context/Context; + public fun getData ()Lhep/dataforge/data/DataNode; + public fun getDefaultChainTarget ()Ljava/lang/String; + public fun getDefaultTarget ()Ljava/lang/String; + public fun getLogger ()Lmu/KLogger; + public fun getTargets ()Ljava/util/Map; + public fun getTasks ()Ljava/util/Map; + public fun run (Lhep/dataforge/workspace/Task;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode; +} + +public final class hep/dataforge/workspace/SimpleWorkspace$Companion { +} + +public final class hep/dataforge/workspace/SimpleWorkspaceBuilder : hep/dataforge/workspace/WorkspaceBuilder { + public fun <init> (Lhep/dataforge/context/Context;)V + public fun build ()Lhep/dataforge/workspace/SimpleWorkspace; + public synthetic fun build ()Lhep/dataforge/workspace/Workspace; + public fun getContext ()Lhep/dataforge/context/Context; + public fun getData ()Lhep/dataforge/data/DataTreeBuilder; + public fun getParentContext ()Lhep/dataforge/context/Context; + public fun getTargets ()Ljava/util/Map; + public fun getTasks ()Ljava/util/Set; + public fun setContext (Lhep/dataforge/context/Context;)V + public fun setData (Lhep/dataforge/data/DataTreeBuilder;)V + public fun setTargets (Ljava/util/Map;)V + public fun setTasks (Ljava/util/Set;)V +} + +public abstract interface class hep/dataforge/workspace/Task : hep/dataforge/context/Named, hep/dataforge/meta/descriptors/Described { + public static final field Companion Lhep/dataforge/workspace/Task$Companion; + public static final field TYPE Ljava/lang/String; + public abstract fun build (Lhep/dataforge/workspace/Workspace;Lhep/dataforge/meta/Meta;)Lhep/dataforge/workspace/TaskModel; + public abstract fun getType ()Lkotlin/reflect/KClass; + public abstract fun isTerminal ()Z + public abstract fun run (Lhep/dataforge/workspace/Workspace;Lhep/dataforge/workspace/TaskModel;)Lhep/dataforge/data/DataNode; + public abstract fun validate (Lhep/dataforge/workspace/TaskModel;)V +} + +public final class hep/dataforge/workspace/Task$Companion { + public static final field TYPE Ljava/lang/String; +} + +public final class hep/dataforge/workspace/Task$DefaultImpls { + public static fun isTerminal (Lhep/dataforge/workspace/Task;)Z + public static fun validate (Lhep/dataforge/workspace/Task;Lhep/dataforge/workspace/TaskModel;)V +} + +public final class hep/dataforge/workspace/TaskBuilder { + public fun <init> (Lhep/dataforge/names/Name;Lkotlin/reflect/KClass;)V + public final fun description (Lkotlin/jvm/functions/Function1;)V + public final fun getName ()Lhep/dataforge/names/Name; + public final fun getType ()Lkotlin/reflect/KClass; + public final fun model (Lkotlin/jvm/functions/Function2;)V + public final fun rawTransform (Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun rawTransform$default (Lhep/dataforge/workspace/TaskBuilder;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V + public final fun transform (Lkotlin/reflect/KClass;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function2;)V + public static synthetic fun transform$default (Lhep/dataforge/workspace/TaskBuilder;Lkotlin/reflect/KClass;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)V +} + +public final class hep/dataforge/workspace/TaskBuilder$TaskEnv { + public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Lhep/dataforge/context/Context;Lhep/dataforge/data/DataNode;)V + public final fun getContext ()Lhep/dataforge/context/Context; + public final fun getData ()Lhep/dataforge/data/DataNode; + public final fun getMeta ()Lhep/dataforge/meta/Meta; + public final fun getName ()Lhep/dataforge/names/Name; + public final fun invoke (Lhep/dataforge/workspace/DirectTaskDependency;)Lhep/dataforge/data/DataNode; +} + +public abstract class hep/dataforge/workspace/TaskDependency : hep/dataforge/workspace/Dependency { + public fun <init> (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/Name;)V + public synthetic fun <init> (Lhep/dataforge/meta/Meta;Lhep/dataforge/names/Name;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun apply (Lhep/dataforge/workspace/Workspace;)Lhep/dataforge/data/DataNode; + public final fun getMeta ()Lhep/dataforge/meta/Meta; + public abstract fun getName ()Lhep/dataforge/names/Name; + public final fun getPlacement ()Lhep/dataforge/names/Name; + public abstract fun resolveTask (Lhep/dataforge/workspace/Workspace;)Lhep/dataforge/workspace/Task; + public fun toMeta ()Lhep/dataforge/meta/Meta; +} + +public abstract interface class hep/dataforge/workspace/TaskDependencyContainer { + public abstract fun add (Lhep/dataforge/workspace/Dependency;)V + public abstract fun getDefaultMeta ()Lhep/dataforge/meta/Meta; +} + +public final class hep/dataforge/workspace/TaskModel : hep/dataforge/meta/MetaRepr { + public static final field Companion Lhep/dataforge/workspace/TaskModel$Companion; + public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Ljava/util/Collection;)V + public final fun component1 ()Lhep/dataforge/names/Name; + public final fun component2 ()Lhep/dataforge/meta/Meta; + public final fun component3 ()Ljava/util/Collection; + public final fun copy (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Ljava/util/Collection;)Lhep/dataforge/workspace/TaskModel; + public static synthetic fun copy$default (Lhep/dataforge/workspace/TaskModel;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Ljava/util/Collection;ILjava/lang/Object;)Lhep/dataforge/workspace/TaskModel; + public fun equals (Ljava/lang/Object;)Z + public final fun getDependencies ()Ljava/util/Collection; + public final fun getMeta ()Lhep/dataforge/meta/Meta; + public final fun getName ()Lhep/dataforge/names/Name; + public fun hashCode ()I + public fun toMeta ()Lhep/dataforge/meta/Meta; + public fun toString ()Ljava/lang/String; +} + +public final class hep/dataforge/workspace/TaskModel$Companion { + public final fun getMODEL_TARGET_KEY ()Lhep/dataforge/names/Name; +} + +public final class hep/dataforge/workspace/TaskModelBuilder : hep/dataforge/workspace/TaskDependencyContainer { + public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)V + public synthetic fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun add (Lhep/dataforge/workspace/Dependency;)V + public final fun build ()Lhep/dataforge/workspace/TaskModel; + public fun getDefaultMeta ()Lhep/dataforge/meta/Meta; + public final fun getMeta ()Lhep/dataforge/meta/MetaBuilder; + public final fun getName ()Lhep/dataforge/names/Name; + public final fun getTarget ()Ljava/lang/String; + public final fun setMeta (Lhep/dataforge/meta/MetaBuilder;)V + public final fun setTarget (Ljava/lang/String;)V +} + +public final class hep/dataforge/workspace/TaskModelKt { + public static final fun allData (Lhep/dataforge/workspace/TaskDependencyContainer;Lhep/dataforge/names/Name;)Lhep/dataforge/workspace/AllDataDependency; + public static synthetic fun allData$default (Lhep/dataforge/workspace/TaskDependencyContainer;Lhep/dataforge/names/Name;ILjava/lang/Object;)Lhep/dataforge/workspace/AllDataDependency; + public static final fun buildInput (Lhep/dataforge/workspace/TaskModel;Lhep/dataforge/workspace/Workspace;)Lhep/dataforge/data/DataTree; + public static final fun data (Lhep/dataforge/workspace/TaskDependencyContainer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lhep/dataforge/workspace/DataDependency; + public static final fun data (Lhep/dataforge/workspace/TaskDependencyContainer;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/workspace/DataDependency; + public static synthetic fun data$default (Lhep/dataforge/workspace/TaskDependencyContainer;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/Object;)Lhep/dataforge/workspace/DataDependency; + public static final fun dependsOn (Lhep/dataforge/workspace/TaskDependencyContainer;Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)Lhep/dataforge/workspace/WorkspaceTaskDependency; + public static final fun dependsOn (Lhep/dataforge/workspace/TaskDependencyContainer;Lhep/dataforge/workspace/Task;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)Lhep/dataforge/workspace/DirectTaskDependency; + public static final fun dependsOn (Lhep/dataforge/workspace/TaskDependencyContainer;Lhep/dataforge/workspace/Task;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/workspace/DirectTaskDependency; + public static final fun dependsOn (Lhep/dataforge/workspace/TaskDependencyContainer;Lhep/dataforge/workspace/Task;Ljava/lang/String;Lhep/dataforge/meta/Meta;)Lhep/dataforge/workspace/DirectTaskDependency; + public static final fun dependsOn (Lhep/dataforge/workspace/TaskDependencyContainer;Ljava/lang/String;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;)Lhep/dataforge/workspace/WorkspaceTaskDependency; + public static synthetic fun dependsOn$default (Lhep/dataforge/workspace/TaskDependencyContainer;Lhep/dataforge/names/Name;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/workspace/WorkspaceTaskDependency; + public static synthetic fun dependsOn$default (Lhep/dataforge/workspace/TaskDependencyContainer;Lhep/dataforge/workspace/Task;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/workspace/DirectTaskDependency; + public static synthetic fun dependsOn$default (Lhep/dataforge/workspace/TaskDependencyContainer;Lhep/dataforge/workspace/Task;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/workspace/DirectTaskDependency; + public static synthetic fun dependsOn$default (Lhep/dataforge/workspace/TaskDependencyContainer;Lhep/dataforge/workspace/Task;Ljava/lang/String;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/workspace/DirectTaskDependency; + public static synthetic fun dependsOn$default (Lhep/dataforge/workspace/TaskDependencyContainer;Ljava/lang/String;Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;ILjava/lang/Object;)Lhep/dataforge/workspace/WorkspaceTaskDependency; + public static final fun getTarget (Lhep/dataforge/workspace/TaskModel;)Ljava/lang/String; +} + +public abstract interface class hep/dataforge/workspace/Workspace : hep/dataforge/context/ContextAware, hep/dataforge/provider/Provider { + public static final field Companion Lhep/dataforge/workspace/Workspace$Companion; + public static final field TYPE Ljava/lang/String; + public abstract fun content (Ljava/lang/String;)Ljava/util/Map; + public abstract fun getData ()Lhep/dataforge/data/DataNode; + public abstract fun getTargets ()Ljava/util/Map; + public abstract fun getTasks ()Ljava/util/Map; + public abstract fun run (Lhep/dataforge/workspace/Task;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode; +} + +public final class hep/dataforge/workspace/Workspace$Companion { + public static final field TYPE Ljava/lang/String; + public final fun invoke (Lhep/dataforge/context/Context;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/workspace/SimpleWorkspace; + public static synthetic fun invoke$default (Lhep/dataforge/workspace/Workspace$Companion;Lhep/dataforge/context/Context;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/workspace/SimpleWorkspace; +} + +public final class hep/dataforge/workspace/Workspace$DefaultImpls { + public static fun content (Lhep/dataforge/workspace/Workspace;Ljava/lang/String;)Ljava/util/Map; + public static fun getDefaultChainTarget (Lhep/dataforge/workspace/Workspace;)Ljava/lang/String; + public static fun getDefaultTarget (Lhep/dataforge/workspace/Workspace;)Ljava/lang/String; + public static fun getLogger (Lhep/dataforge/workspace/Workspace;)Lmu/KLogger; + public static fun run (Lhep/dataforge/workspace/Workspace;Lhep/dataforge/workspace/Task;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode; +} + +public abstract interface class hep/dataforge/workspace/WorkspaceBuilder { + public abstract fun build ()Lhep/dataforge/workspace/Workspace; + public abstract fun getContext ()Lhep/dataforge/context/Context; + public abstract fun getData ()Lhep/dataforge/data/DataTreeBuilder; + public abstract fun getParentContext ()Lhep/dataforge/context/Context; + public abstract fun getTargets ()Ljava/util/Map; + public abstract fun getTasks ()Ljava/util/Set; + public abstract fun setContext (Lhep/dataforge/context/Context;)V + public abstract fun setData (Lhep/dataforge/data/DataTreeBuilder;)V + public abstract fun setTargets (Ljava/util/Map;)V + public abstract fun setTasks (Ljava/util/Set;)V +} + +public final class hep/dataforge/workspace/WorkspaceBuilderKt { + public static final fun context (Lhep/dataforge/workspace/WorkspaceBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public static synthetic fun context$default (Lhep/dataforge/workspace/WorkspaceBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V + public static final fun rawData (Lhep/dataforge/workspace/WorkspaceBuilder;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/data/DataNode; + public static synthetic fun rawData$default (Lhep/dataforge/workspace/WorkspaceBuilder;Lhep/dataforge/names/Name;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/data/DataNode; + public static final fun rawTask (Lhep/dataforge/workspace/WorkspaceBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/workspace/Task; + public static final fun target (Lhep/dataforge/workspace/WorkspaceBuilder;Ljava/lang/String;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public static final fun target (Lhep/dataforge/workspace/WorkspaceBuilder;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)V + public static final fun task (Lhep/dataforge/workspace/WorkspaceBuilder;Ljava/lang/String;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/workspace/Task; +} + +public final class hep/dataforge/workspace/WorkspaceKt { + public static final fun run (Lhep/dataforge/workspace/Workspace;Lhep/dataforge/workspace/Task;Ljava/lang/String;)Lhep/dataforge/data/DataNode; + public static final fun run (Lhep/dataforge/workspace/Workspace;Lhep/dataforge/workspace/Task;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/data/DataNode; + public static final fun run (Lhep/dataforge/workspace/Workspace;Ljava/lang/String;Lhep/dataforge/meta/Meta;)Lhep/dataforge/data/DataNode; + public static final fun run (Lhep/dataforge/workspace/Workspace;Ljava/lang/String;Ljava/lang/String;)Lhep/dataforge/data/DataNode; + public static final fun run (Lhep/dataforge/workspace/Workspace;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/data/DataNode; + public static synthetic fun run$default (Lhep/dataforge/workspace/Workspace;Lhep/dataforge/workspace/Task;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/data/DataNode; + public static synthetic fun run$default (Lhep/dataforge/workspace/Workspace;Ljava/lang/String;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lhep/dataforge/data/DataNode; +} + +public abstract class hep/dataforge/workspace/WorkspacePlugin : hep/dataforge/context/AbstractPlugin { + public fun <init> ()V + public fun content (Ljava/lang/String;)Ljava/util/Map; + public final fun getTasks ()Ljava/util/Collection; + public final fun task (Lhep/dataforge/workspace/Task;)V + public final fun task (Ljava/lang/String;Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)Lhep/dataforge/workspace/GenericTask; +} + +public final class hep/dataforge/workspace/WorkspaceTaskDependency : hep/dataforge/workspace/TaskDependency { + public fun <init> (Lhep/dataforge/names/Name;Lhep/dataforge/meta/Meta;Lhep/dataforge/names/Name;)V + public fun getName ()Lhep/dataforge/names/Name; + public fun resolveTask (Lhep/dataforge/workspace/Workspace;)Lhep/dataforge/workspace/Task; +} + diff --git a/dataforge-workspace/build.gradle.kts b/dataforge-workspace/build.gradle.kts index c576ef8e..2bb03cec 100644 --- a/dataforge-workspace/build.gradle.kts +++ b/dataforge-workspace/build.gradle.kts @@ -1,16 +1,15 @@ plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") + id("ru.mipt.npm.native") } kotlin { - jvm() - js() sourceSets { - val commonMain by getting{ + commonMain{ dependencies { api(project(":dataforge-context")) api(project(":dataforge-data")) - api(project(":dataforge-output")) + api(project(":dataforge-io")) } } } diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Dependency.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Dependency.kt index ed5ab7f0..e58a988b 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Dependency.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Dependency.kt @@ -4,6 +4,7 @@ import hep.dataforge.data.DataFilter import hep.dataforge.data.DataNode import hep.dataforge.data.filter import hep.dataforge.meta.Meta +import hep.dataforge.meta.MetaBuilder import hep.dataforge.meta.MetaRepr import hep.dataforge.names.Name import hep.dataforge.names.asName @@ -13,11 +14,11 @@ import hep.dataforge.names.plus /** * A dependency of the task which allows to lazily create a data tree for single dependency */ -sealed class Dependency : MetaRepr { - abstract fun apply(workspace: Workspace): DataNode<Any> +public sealed class Dependency : MetaRepr { + public abstract fun apply(workspace: Workspace): DataNode<Any> } -class DataDependency(val filter: DataFilter, val placement: Name = Name.EMPTY) : Dependency() { +public class DataDependency(private val filter: DataFilter, private val placement: Name = Name.EMPTY) : Dependency() { override fun apply(workspace: Workspace): DataNode<Any> { val result = workspace.data.filter(filter) return if (placement.isEmpty()) { @@ -28,34 +29,34 @@ class DataDependency(val filter: DataFilter, val placement: Name = Name.EMPTY) : } override fun toMeta(): Meta = Meta { - "data" put filter.config + "data" put filter.toMeta() "to" put placement.toString() } } -class AllDataDependency(val placement: Name = Name.EMPTY) : Dependency() { +public class AllDataDependency(private val placement: Name = Name.EMPTY) : Dependency() { override fun apply(workspace: Workspace): DataNode<Any> = if (placement.isEmpty()) { workspace.data } else { DataNode.invoke(Any::class) { this[placement] = workspace.data } } - override fun toMeta() = Meta { + override fun toMeta(): MetaBuilder = Meta { "data" put "@all" "to" put placement.toString() } } -abstract class TaskDependency<out T : Any>( - val meta: Meta, - val placement: Name = Name.EMPTY +public abstract class TaskDependency<out T : Any>( + public val meta: Meta, + public val placement: Name = Name.EMPTY ) : Dependency() { - abstract fun resolveTask(workspace: Workspace): Task<T> + public abstract fun resolveTask(workspace: Workspace): Task<T> /** * A name of the dependency for logging and serialization */ - abstract val name: Name + public abstract val name: Name override fun apply(workspace: Workspace): DataNode<T> { val task = resolveTask(workspace) @@ -75,8 +76,8 @@ abstract class TaskDependency<out T : Any>( } } -class DirectTaskDependency<T : Any>( - val task: Task<T>, +public class DirectTaskDependency<T : Any>( + public val task: Task<T>, meta: Meta, placement: Name ) : TaskDependency<T>(meta, placement) { @@ -84,12 +85,12 @@ class DirectTaskDependency<T : Any>( override val name: Name get() = DIRECT_TASK_NAME + task.name - companion object { - val DIRECT_TASK_NAME = "@direct".asName() + public companion object { + public val DIRECT_TASK_NAME: Name = "@direct".asName() } } -class WorkspaceTaskDependency( +public class WorkspaceTaskDependency( override val name: Name, meta: Meta, placement: Name diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/GenericTask.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/GenericTask.kt index 4e0ca715..d3844096 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/GenericTask.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/GenericTask.kt @@ -1,8 +1,8 @@ package hep.dataforge.workspace import hep.dataforge.data.DataNode -import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.Meta +import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.get import hep.dataforge.meta.node import hep.dataforge.names.Name @@ -11,7 +11,7 @@ import kotlin.reflect.KClass //data class TaskEnv(val workspace: Workspace, val model: TaskModel) -class GenericTask<R : Any>( +public class GenericTask<R : Any>( override val name: Name, override val type: KClass<out R>, override val descriptor: NodeDescriptor, @@ -19,14 +19,6 @@ class GenericTask<R : Any>( private val dataTransform: Workspace.() -> TaskModel.(DataNode<Any>) -> DataNode<R> ) : Task<R> { -// private fun gather(workspace: Workspace, model: TaskModel): DataNode<Any> { -// return DataNode.invoke(Any::class) { -// model.dependencies.forEach { dep -> -// update(dep.apply(workspace)) -// } -// } -// } - override fun run(workspace: Workspace, model: TaskModel): DataNode<R> { //validate model validate(model) diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/SimpleWorkspace.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/SimpleWorkspace.kt index c94fd8ca..adec8bb9 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/SimpleWorkspace.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/SimpleWorkspace.kt @@ -1,7 +1,7 @@ package hep.dataforge.workspace import hep.dataforge.context.Context -import hep.dataforge.context.content +import hep.dataforge.context.gather import hep.dataforge.context.toMap import hep.dataforge.data.DataNode import hep.dataforge.meta.Meta @@ -11,7 +11,7 @@ import hep.dataforge.names.Name /** * A simple workspace without caching */ -class SimpleWorkspace( +public class SimpleWorkspace( override val context: Context, override val data: DataNode<Any>, override val targets: Map<String, Meta>, @@ -19,10 +19,10 @@ class SimpleWorkspace( ) : Workspace { override val tasks: Map<Name, Task<*>> by lazy { - context.content<Task<*>>(Task.TYPE) + tasks.toMap() + context.gather<Task<*>>(Task.TYPE) + tasks.toMap() } - companion object { + public companion object { } } \ No newline at end of file diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Task.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Task.kt index 7511bda9..6792adfa 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Task.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Task.kt @@ -2,23 +2,23 @@ package hep.dataforge.workspace import hep.dataforge.context.Named import hep.dataforge.data.DataNode -import hep.dataforge.meta.descriptors.Described import hep.dataforge.meta.Meta +import hep.dataforge.meta.descriptors.Described import hep.dataforge.provider.Type import hep.dataforge.workspace.Task.Companion.TYPE import kotlin.reflect.KClass @Type(TYPE) -interface Task<out R : Any> : Named, Described { +public interface Task<out R : Any> : Named, Described { /** * Terminal task is the one that could not build model lazily */ - val isTerminal: Boolean get() = false + public val isTerminal: Boolean get() = false /** * The explicit type of the node returned by the task */ - val type: KClass<out R> + public val type: KClass<out R> /** * Build a model for this task @@ -27,14 +27,14 @@ interface Task<out R : Any> : Named, Described { * @param taskConfig * @return */ - fun build(workspace: Workspace, taskConfig: Meta): TaskModel + public fun build(workspace: Workspace, taskConfig: Meta): TaskModel /** * Check if the model is valid and is acceptable by the task. Throw exception if not. * * @param model */ - fun validate(model: TaskModel) { + public fun validate(model: TaskModel) { if(this.name != model.name) error("The task $name could not be run with model from task ${model.name}") } @@ -46,9 +46,9 @@ interface Task<out R : Any> : Named, Described { * @param model - a model to be executed * @return */ - fun run(workspace: Workspace, model: TaskModel): DataNode<R> + public fun run(workspace: Workspace, model: TaskModel): DataNode<R> - companion object { - const val TYPE = "task" + public companion object { + public const val TYPE: String = "task" } } \ No newline at end of file diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/TaskBuilder.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/TaskBuilder.kt index 502c669d..4cb48843 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/TaskBuilder.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/TaskBuilder.kt @@ -14,11 +14,11 @@ import kotlin.jvm.JvmName import kotlin.reflect.KClass @DFBuilder -class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { +public class TaskBuilder<R : Any>(public val name: Name, public val type: KClass<out R>) { private var modelTransform: TaskModelBuilder.(Meta) -> Unit = { allData() } // private val additionalDependencies = HashSet<Dependency>() - var descriptor: NodeDescriptor? = null + private var descriptor: NodeDescriptor? = null private val dataTransforms: MutableList<DataTransformation> = ArrayList() /** @@ -43,7 +43,7 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { // additionalDependencies.add(dependency) // } - fun model(modelTransform: TaskModelBuilder.(Meta) -> Unit) { + public fun model(modelTransform: TaskModelBuilder.(Meta) -> Unit) { this.modelTransform = modelTransform } @@ -51,7 +51,7 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { * Add a transformation on untyped data */ @JvmName("rawTransform") - fun transform( + public fun transform( from: String = "", to: String = "", block: TaskEnv.(DataNode<*>) -> DataNode<R> @@ -62,7 +62,7 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { } } - fun <T : Any> transform( + public fun <T : Any> transform( inputType: KClass<out T>, from: String = "", to: String = "", @@ -75,7 +75,7 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { } } - inline fun <reified T : Any> transform( + public inline fun <reified T : Any> transform( from: String = "", to: String = "", noinline block: TaskEnv.(DataNode<T>) -> DataNode<R> @@ -86,7 +86,7 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { /** * Perform given action on data elements in `from` node in input and put the result to `to` node */ - inline fun <reified T : Any> action( + public inline fun <reified T : Any> action( from: String = "", to: String = "", crossinline block: TaskEnv.() -> Action<T, R> @@ -96,8 +96,8 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { } } - class TaskEnv(val name: Name, val meta: Meta, val context: Context, val data: DataNode<Any>) { - operator fun <T : Any> DirectTaskDependency<T>.invoke(): DataNode<T> = if (placement.isEmpty()) { + public class TaskEnv(public val name: Name, public val meta: Meta, public val context: Context, public val data: DataNode<Any>) { + public operator fun <T : Any> DirectTaskDependency<T>.invoke(): DataNode<T> = if (placement.isEmpty()) { data.cast(task.type) } else { data[placement].node?.cast(task.type) @@ -108,7 +108,7 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { /** * A customized map action with ability to change meta and name */ - inline fun <reified T : Any> mapAction( + public inline fun <reified T : Any> mapAction( from: String = "", to: String = "", crossinline block: MapActionBuilder<T, R>.(TaskEnv) -> Unit @@ -127,7 +127,7 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { /** * A simple map action without changing meta or name */ - inline fun <reified T : Any> map( + public inline fun <reified T : Any> map( from: String = "", to: String = "", crossinline block: suspend TaskEnv.(T) -> R @@ -148,7 +148,7 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { /** * Join elements in gathered data by multiple groups */ - inline fun <reified T : Any> reduceByGroup( + public inline fun <reified T : Any> reduceByGroup( from: String = "", to: String = "", crossinline block: ReduceGroupBuilder<T, R>.(TaskEnv) -> Unit //TODO needs KEEP-176 @@ -165,7 +165,7 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { /** * Join all elemlents in gathered data matching input type */ - inline fun <reified T : Any> reduce( + public inline fun <reified T : Any> reduce( from: String = "", to: String = "", crossinline block: suspend TaskEnv.(Map<Name, T>) -> R @@ -188,7 +188,7 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { /** * Split each element in gathered data into fixed number of fragments */ - inline fun <reified T : Any> split( + public inline fun <reified T : Any> split( from: String = "", to: String = "", crossinline block: SplitBuilder<T, R>.(TaskEnv) -> Unit //TODO needs KEEP-176 @@ -205,16 +205,11 @@ class TaskBuilder<R : Any>(val name: Name, val type: KClass<out R>) { /** * Use DSL to create a descriptor for this task */ - fun description(transform: NodeDescriptor.() -> Unit) { + public fun description(transform: NodeDescriptor.() -> Unit) { this.descriptor = NodeDescriptor().apply(transform) } internal fun build(): GenericTask<R> { -// val actualTransform: TaskModelBuilder.(Meta) -> Unit = { -// modelTransform -// dependencies.addAll(additionalDependencies) -// } - return GenericTask( name, type, diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/TaskModel.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/TaskModel.kt index acd16b2d..5053292e 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/TaskModel.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/TaskModel.kt @@ -21,7 +21,7 @@ import hep.dataforge.workspace.TaskModel.Companion.MODEL_TARGET_KEY * @param meta the meta for the task (not for the whole configuration) * @param dependencies a list of direct dependencies for this task */ -data class TaskModel( +public data class TaskModel( val name: Name, val meta: Meta, val dependencies: Collection<Dependency> @@ -45,15 +45,15 @@ data class TaskModel( } } - companion object { - val MODEL_TARGET_KEY = "@target".asName() + public companion object { + public val MODEL_TARGET_KEY: Name = "@target".asName() } } /** * Build input for the task */ -fun TaskModel.buildInput(workspace: Workspace): DataTree<Any> { +public fun TaskModel.buildInput(workspace: Workspace): DataTree<Any> { return DataTreeBuilder(Any::class).apply { dependencies.forEach { dep -> update(dep.apply(workspace)) @@ -61,43 +61,43 @@ fun TaskModel.buildInput(workspace: Workspace): DataTree<Any> { }.build() } -interface TaskDependencyContainer { - val defaultMeta: Meta - fun add(dependency: Dependency) +public interface TaskDependencyContainer { + public val defaultMeta: Meta + public fun add(dependency: Dependency) } /** * Add dependency for a task defined in a workspace and resolved by */ -fun TaskDependencyContainer.dependsOn( +public fun TaskDependencyContainer.dependsOn( name: Name, placement: Name = Name.EMPTY, meta: Meta = defaultMeta ): WorkspaceTaskDependency = WorkspaceTaskDependency(name, meta, placement).also { add(it) } -fun TaskDependencyContainer.dependsOn( +public fun TaskDependencyContainer.dependsOn( name: String, placement: Name = Name.EMPTY, meta: Meta = defaultMeta ): WorkspaceTaskDependency = dependsOn(name.toName(), placement, meta) -fun <T : Any> TaskDependencyContainer.dependsOn( +public fun <T : Any> TaskDependencyContainer.dependsOn( task: Task<T>, placement: Name = Name.EMPTY, meta: Meta = defaultMeta ): DirectTaskDependency<T> = DirectTaskDependency(task, meta, placement).also { add(it) } -fun <T : Any> TaskDependencyContainer.dependsOn( +public fun <T : Any> TaskDependencyContainer.dependsOn( task: Task<T>, placement: String, meta: Meta = defaultMeta ): DirectTaskDependency<T> = DirectTaskDependency(task, meta, placement.toName()).also { add(it) } -fun <T : Any> TaskDependencyContainer.dependsOn( +public fun <T : Any> TaskDependencyContainer.dependsOn( task: Task<T>, placement: Name = Name.EMPTY, metaBuilder: MetaBuilder.() -> Unit @@ -107,13 +107,13 @@ fun <T : Any> TaskDependencyContainer.dependsOn( /** * Add custom data dependency */ -fun TaskDependencyContainer.data(action: DataFilter.() -> Unit): DataDependency = +public fun TaskDependencyContainer.data(action: DataFilter.() -> Unit): DataDependency = DataDependency(DataFilter(action)).also { add(it) } /** * User-friendly way to add data dependency */ -fun TaskDependencyContainer.data(pattern: String? = null, from: String? = null, to: String? = null): DataDependency = +public fun TaskDependencyContainer.data(pattern: String? = null, from: String? = null, to: String? = null): DataDependency = data { pattern?.let { this.pattern = it } from?.let { this.from = it } @@ -123,17 +123,17 @@ fun TaskDependencyContainer.data(pattern: String? = null, from: String? = null, /** * Add all data as root node */ -fun TaskDependencyContainer.allData(to: Name = Name.EMPTY) = AllDataDependency(to).also { add(it) } +public fun TaskDependencyContainer.allData(to: Name = Name.EMPTY): AllDataDependency = AllDataDependency(to).also { add(it) } /** * A builder for [TaskModel] */ -class TaskModelBuilder(val name: Name, meta: Meta = Meta.EMPTY) : TaskDependencyContainer { +public class TaskModelBuilder(public val name: Name, meta: Meta = Meta.EMPTY) : TaskDependencyContainer { /** * Meta for current task. By default uses the whole input meta */ - var meta: MetaBuilder = meta.builder() - val dependencies = HashSet<Dependency>() + public var meta: MetaBuilder = meta.builder() + private val dependencies: HashSet<Dependency> = HashSet<Dependency>() override val defaultMeta: Meta get() = meta @@ -141,11 +141,11 @@ class TaskModelBuilder(val name: Name, meta: Meta = Meta.EMPTY) : TaskDependency dependencies.add(dependency) } - var target: String by this.meta.string(key = MODEL_TARGET_KEY, default = "") + public var target: String by this.meta.string(key = MODEL_TARGET_KEY, default = "") - fun build(): TaskModel = TaskModel(name, meta.seal(), dependencies) + public fun build(): TaskModel = TaskModel(name, meta.seal(), dependencies) } -val TaskModel.target get() = meta[MODEL_TARGET_KEY]?.string ?: "" \ No newline at end of file +public val TaskModel.target: String get() = meta[MODEL_TARGET_KEY]?.string ?: "" \ No newline at end of file diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Workspace.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Workspace.kt index ac2b1131..b9aaad18 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Workspace.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/Workspace.kt @@ -15,23 +15,23 @@ import hep.dataforge.provider.Type @Type(Workspace.TYPE) -interface Workspace : ContextAware, Provider { +public interface Workspace : ContextAware, Provider { /** * The whole data node for current workspace */ - val data: DataNode<Any> + public val data: DataNode<Any> /** * All targets associated with the workspace */ - val targets: Map<String, Meta> + public val targets: Map<String, Meta> /** * All tasks associated with the workspace */ - val tasks: Map<Name, Task<*>> + public val tasks: Map<Name, Task<*>> - override fun provideTop(target: String): Map<Name, Any> { + override fun content(target: String): Map<Name, Any> { return when (target) { "target", Meta.TYPE -> targets.mapKeys { it.key.toName() } Task.TYPE -> tasks @@ -44,38 +44,36 @@ interface Workspace : ContextAware, Provider { /** * Invoke a task in the workspace utilizing caching if possible */ - fun <R : Any> run(task: Task<R>, config: Meta): DataNode<R> { - context.activate(this) - try { - val model = task.build(this, config) - task.validate(model) - return task.run(this, model) - } finally { - context.deactivate(this) - } + public fun <R : Any> run(task: Task<R>, config: Meta): DataNode<R> { + val model = task.build(this, config) + task.validate(model) + return task.run(this, model) } - companion object { - const val TYPE = "workspace" - operator fun invoke(parent: Context = Global, block: SimpleWorkspaceBuilder.() -> Unit): SimpleWorkspace = + public companion object { + public const val TYPE: String = "workspace" + public operator fun invoke( + parent: Context = Global, + block: SimpleWorkspaceBuilder.() -> Unit, + ): SimpleWorkspace = SimpleWorkspaceBuilder(parent).apply(block).build() } } -fun Workspace.run(task: Task<*>, target: String): DataNode<Any> { - val meta = targets[target] ?: error("A target with name $target not found in ${this}") +public fun Workspace.run(task: Task<*>, target: String): DataNode<Any> { + val meta = targets[target] ?: error("A target with name $target not found in $this") return run(task, meta) } -fun Workspace.run(task: String, target: String) = +public fun Workspace.run(task: String, target: String): DataNode<Any> = tasks[task.toName()]?.let { run(it, target) } ?: error("Task with name $task not found") -fun Workspace.run(task: String, meta: Meta) = +public fun Workspace.run(task: String, meta: Meta): DataNode<Any> = tasks[task.toName()]?.let { run(it, meta) } ?: error("Task with name $task not found") -fun Workspace.run(task: String, block: MetaBuilder.() -> Unit = {}) = +public fun Workspace.run(task: String, block: MetaBuilder.() -> Unit = {}): DataNode<Any> = run(task, Meta(block)) -fun <T: Any> Workspace.run(task: Task<T>, metaBuilder: MetaBuilder.() -> Unit = {}): DataNode<T> = +public fun <T : Any> Workspace.run(task: Task<T>, metaBuilder: MetaBuilder.() -> Unit = {}): DataNode<T> = run(task, Meta(metaBuilder)) \ No newline at end of file diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspaceBuilder.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspaceBuilder.kt index 3bc1ffcf..b7f74079 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspaceBuilder.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspaceBuilder.kt @@ -12,25 +12,25 @@ import kotlin.jvm.JvmName import kotlin.reflect.KClass @DFBuilder -interface WorkspaceBuilder { - val parentContext: Context - var context: Context - var data: DataTreeBuilder<Any> - var tasks: MutableSet<Task<Any>> - var targets: MutableMap<String, Meta> +public interface WorkspaceBuilder { + public val parentContext: Context + public var context: Context + public var data: DataTreeBuilder<Any> + public var tasks: MutableSet<Task<Any>> + public var targets: MutableMap<String, Meta> - fun build(): Workspace + public fun build(): Workspace } /** * Set the context for future workspcace */ -fun WorkspaceBuilder.context(name: String = "WORKSPACE", block: ContextBuilder.() -> Unit = {}) { - context = ContextBuilder(name, parentContext).apply(block).build() +public fun WorkspaceBuilder.context(name: String = "WORKSPACE", block: ContextBuilder.() -> Unit = {}) { + context = ContextBuilder(parentContext, name).apply(block).build() } -inline fun <reified T : Any> WorkspaceBuilder.data( +public inline fun <reified T : Any> WorkspaceBuilder.data( name: Name = Name.EMPTY, noinline block: DataTreeBuilder<T>.() -> Unit ): DataNode<T> { @@ -45,20 +45,20 @@ inline fun <reified T : Any> WorkspaceBuilder.data( } @JvmName("rawData") -fun WorkspaceBuilder.data( +public fun WorkspaceBuilder.data( name: Name = Name.EMPTY, block: DataTreeBuilder<Any>.() -> Unit ): DataNode<Any> = data<Any>(name, block) -fun WorkspaceBuilder.target(name: String, block: MetaBuilder.() -> Unit) { +public fun WorkspaceBuilder.target(name: String, block: MetaBuilder.() -> Unit) { targets[name] = Meta(block).seal() } /** * Use existing target as a base updating it with the block */ -fun WorkspaceBuilder.target(name: String, base: String, block: MetaBuilder.() -> Unit) { +public fun WorkspaceBuilder.target(name: String, base: String, block: MetaBuilder.() -> Unit) { val parentTarget = targets[base] ?: error("Base target with name $base not found") targets[name] = parentTarget.builder() .apply { "@baseTarget" put base } @@ -66,19 +66,19 @@ fun WorkspaceBuilder.target(name: String, base: String, block: MetaBuilder.() -> .seal() } -fun <T : Any> WorkspaceBuilder.task( +public fun <T : Any> WorkspaceBuilder.task( name: String, type: KClass<out T>, builder: TaskBuilder<T>.() -> Unit ): Task<T> = TaskBuilder(name.toName(), type).apply(builder).build().also { tasks.add(it) } -inline fun <reified T : Any> WorkspaceBuilder.task( +public inline fun <reified T : Any> WorkspaceBuilder.task( name: String, noinline builder: TaskBuilder<T>.() -> Unit ): Task<T> = task(name, T::class, builder) @JvmName("rawTask") -fun WorkspaceBuilder.task( +public fun WorkspaceBuilder.task( name: String, builder: TaskBuilder<Any>.() -> Unit ): Task<Any> = task(name, Any::class, builder) @@ -86,7 +86,7 @@ fun WorkspaceBuilder.task( /** * A builder for a simple workspace */ -class SimpleWorkspaceBuilder(override val parentContext: Context) : WorkspaceBuilder { +public class SimpleWorkspaceBuilder(override val parentContext: Context) : WorkspaceBuilder { override var context: Context = parentContext override var data: DataTreeBuilder<Any> = DataTreeBuilder(Any::class) override var tasks: MutableSet<Task<Any>> = HashSet() diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspacePlugin.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspacePlugin.kt index a377c023..9079139d 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspacePlugin.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/WorkspacePlugin.kt @@ -9,22 +9,22 @@ import kotlin.reflect.KClass /** * An abstract plugin with some additional boilerplate to effectively work with workspace context */ -abstract class WorkspacePlugin : AbstractPlugin() { +public abstract class WorkspacePlugin : AbstractPlugin() { private val _tasks = HashSet<Task<*>>() - val tasks: Collection<Task<*>> get() = _tasks + public val tasks: Collection<Task<*>> get() = _tasks - override fun provideTop(target: String): Map<Name, Any> { + override fun content(target: String): Map<Name, Any> { return when (target) { Task.TYPE -> tasks.toMap() else -> emptyMap() } } - fun task(task: Task<*>){ + public fun task(task: Task<*>){ _tasks.add(task) } - fun <T : Any> task( + public fun <T : Any> task( name: String, type: KClass<out T>, builder: TaskBuilder<T>.() -> Unit @@ -32,10 +32,10 @@ abstract class WorkspacePlugin : AbstractPlugin() { _tasks.add(it) } - inline fun <reified T : Any> task( + public inline fun <reified T : Any> task( name: String, noinline builder: TaskBuilder<T>.() -> Unit - ) = task(name, T::class, builder) + ): GenericTask<T> = task(name, T::class, builder) // ////TODO add delegates to build gradle-like tasks diff --git a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/envelopeData.kt b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/envelopeData.kt index 248e819c..461409e2 100644 --- a/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/envelopeData.kt +++ b/dataforge-workspace/src/commonMain/kotlin/hep/dataforge/workspace/envelopeData.kt @@ -8,11 +8,11 @@ import kotlin.reflect.KClass /** * Convert an [Envelope] to a data via given format. The actual parsing is done lazily. */ -fun <T : Any> Envelope.toData(type: KClass<out T>, format: IOFormat<T>): Data<T> = Data(type, meta) { +public fun <T : Any> Envelope.toData(type: KClass<out T>, format: IOFormat<T>): Data<T> = Data(type, meta) { data?.readWith(format) ?: error("Can't convert envelope without data to Data") } -suspend fun <T : Any> Data<T>.toEnvelope(format: IOFormat<T>): Envelope { +public suspend fun <T : Any> Data<T>.toEnvelope(format: IOFormat<T>): Envelope { val obj = await() val binary = format.toBinary(obj) return SimpleEnvelope(meta, binary) diff --git a/dataforge-workspace/src/jvmMain/kotlin/hep/dataforge/workspace/fileData.kt b/dataforge-workspace/src/jvmMain/kotlin/hep/dataforge/workspace/fileData.kt index 6d16c37d..97ae77e6 100644 --- a/dataforge-workspace/src/jvmMain/kotlin/hep/dataforge/workspace/fileData.kt +++ b/dataforge-workspace/src/jvmMain/kotlin/hep/dataforge/workspace/fileData.kt @@ -36,7 +36,7 @@ private fun newZFS(path: Path): FileSystem { * @param metaFileFormat the meta format for override */ @DFExperimental -fun <T : Any> IOPlugin.readDataFile( +public fun <T : Any> IOPlugin.readDataFile( path: Path, type: KClass<out T>, formatResolver: FileFormatResolver<T> @@ -47,7 +47,7 @@ fun <T : Any> IOPlugin.readDataFile( } @DFExperimental -inline fun <reified T : Any> IOPlugin.readDataFile(path: Path): Data<T> = +public inline fun <reified T : Any> IOPlugin.readDataFile(path: Path): Data<T> = readDataFile(path, T::class) { _, _ -> resolveIOFormat<T>() ?: error("Can't resolve IO format for ${T::class}") } @@ -56,7 +56,7 @@ inline fun <reified T : Any> IOPlugin.readDataFile(path: Path): Data<T> = * Add file/directory-based data tree item */ @DFExperimental -fun <T : Any> DataTreeBuilder<T>.file( +public fun <T : Any> DataTreeBuilder<T>.file( plugin: IOPlugin, path: Path, formatResolver: FileFormatResolver<T> @@ -109,7 +109,7 @@ fun <T : Any> IOPlugin.readDataDirectory( } @DFExperimental -inline fun <reified T : Any> IOPlugin.readDataDirectory(path: Path): DataNode<T> = +public inline fun <reified T : Any> IOPlugin.readDataDirectory(path: Path): DataNode<T> = readDataDirectory(path, T::class) { _, _ -> resolveIOFormat<T>() ?: error("Can't resolve IO format for ${T::class}") } @@ -118,7 +118,7 @@ inline fun <reified T : Any> IOPlugin.readDataDirectory(path: Path): DataNode<T> * Write data tree to existing directory or create a new one using default [java.nio.file.FileSystem] provider */ @DFExperimental -suspend fun <T : Any> IOPlugin.writeDataDirectory( +public suspend fun <T : Any> IOPlugin.writeDataDirectory( path: Path, node: DataNode<T>, format: IOFormat<T>, @@ -168,7 +168,7 @@ private suspend fun <T : Any> ZipOutputStream.writeNode( val entry = ZipEntry(name) putNextEntry(entry) envelopeFormat.run { - asOutput().writeObject(envelope) + writeObject(asOutput(), envelope) } } is DataItem.Node -> { diff --git a/dataforge-workspace/src/jvmTest/kotlin/hep/dataforge/workspace/FileDataTest.kt b/dataforge-workspace/src/jvmTest/kotlin/hep/dataforge/workspace/FileDataTest.kt index 6c9537cc..7357c5c5 100644 --- a/dataforge-workspace/src/jvmTest/kotlin/hep/dataforge/workspace/FileDataTest.kt +++ b/dataforge-workspace/src/jvmTest/kotlin/hep/dataforge/workspace/FileDataTest.kt @@ -30,12 +30,12 @@ class FileDataTest { } object StringIOFormat : IOFormat<String> { - override fun Output.writeObject(obj: String) { - writeUtf8String(obj) + override fun writeObject(output: Output, obj: String) { + output.writeUtf8String(obj) } - override fun Input.readObject(): String { - return readUtf8String() + override fun readObject(input: Input): String { + return input.readUtf8String() } override fun toMeta(): Meta = Meta { diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..a782b701 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,9 @@ +kotlin.code.style=official +kotlin.parallel.tasks.in.project=true +kotlin.mpp.enableGranularSourceSetsMetadata=true +//kotlin.native.enableDependencyPropagation=false +kotlin.mpp.stability.nowarn=true + +org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m +org.gradle.parallel=true +systemProp.org.gradle.internal.publish.checksums.insecure=true \ No newline at end of file diff --git a/gradle/artifactory.gradle b/gradle/artifactory.gradle deleted file mode 100644 index 12e59642..00000000 --- a/gradle/artifactory.gradle +++ /dev/null @@ -1,31 +0,0 @@ -apply plugin: "com.jfrog.artifactory" - -artifactory { - def artifactory_user = project.hasProperty('artifactoryUser') ? project.property('artifactoryUser') : "" - def artifactory_password = project.hasProperty('artifactoryPassword') ? project.property('artifactoryPassword') : "" - def artifactory_contextUrl = 'http://npm.mipt.ru:8081/artifactory' - - contextUrl = artifactory_contextUrl //The base Artifactory URL if not overridden by the publisher/resolver - publish { - repository { - repoKey = 'gradle-dev-local' - username = artifactory_user - password = artifactory_password - } - - defaults { - publications('jvm', 'js', 'kotlinMultiplatform', 'metadata') - publishBuildInfo = false - publishArtifacts = true - publishPom = true - publishIvy = false - } - } - resolve { - repository { - repoKey = 'gradle-dev' - username = artifactory_user - password = artifactory_password - } - } -} \ No newline at end of file diff --git a/gradle/bintray.gradle b/gradle/bintray.gradle deleted file mode 100644 index 8da83c86..00000000 --- a/gradle/bintray.gradle +++ /dev/null @@ -1,85 +0,0 @@ -apply plugin: 'com.jfrog.bintray' - -def vcs = "https://github.com/mipt-npm/kmath" - -def pomConfig = { - licenses { - license { - name "The Apache Software License, Version 2.0" - url "http://www.apache.org/licenses/LICENSE-2.0.txt" - distribution "repo" - } - } - developers { - developer { - id "MIPT-NPM" - name "MIPT nuclear physics methods laboratory" - organization "MIPT" - organizationUrl "http://npm.mipt.ru" - } - } - scm { - url vcs - } -} - -project.ext.configureMavenCentralMetadata = { pom -> - def root = asNode() - root.appendNode('name', project.name) - root.appendNode('description', project.description) - root.appendNode('url', vcs) - root.children().last() + pomConfig -} - -project.ext.configurePom = pomConfig - - -// Configure publishing -publishing { - repositories { - maven { - url = "https://bintray.com/mipt-npm/scientifik" - } - } - - // Process each publication we have in this project - publications.all { publication -> - // apply changes to pom.xml files, see pom.gradle - pom.withXml(configureMavenCentralMetadata) - - - } -} - -bintray { - user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER') - key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY') - publish = true - override = true // for multi-platform Kotlin/Native publishing - - pkg { - userOrg = "mipt-npm" - repo = "scientifik" - name = "scientifik.kmath" - issueTrackerUrl = "https://github.com/mipt-npm/kmath/issues" - licenses = ['Apache-2.0'] - vcsUrl = vcs - version { - name = project.version - vcsTag = project.version - released = new Date() - } - } -} - -bintrayUpload.dependsOn publishToMavenLocal - -// This is for easier debugging of bintray uploading problems -bintrayUpload.doFirst { - publications = project.publishing.publications.findAll { - !it.name.contains('-test') && it.name != 'kotlinMultiplatform' - }.collect { - println("Uploading artifact '$it.groupId:$it.artifactId:$it.version' from publication '$it.name'") - it.name//https://github.com/bintray/gradle-bintray-plugin/issues/256 - } -} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 62d4c053..e708b1c0 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 622ab64a..12d38de6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index fbd7c515..4f906e0c 100755 --- a/gradlew +++ b/gradlew @@ -130,7 +130,7 @@ fi if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath diff --git a/gradlew.bat b/gradlew.bat index 5093609d..107acd32 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -54,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -64,21 +64,6 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line @@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/settings.gradle.kts b/settings.gradle.kts index e0d250bf..1d15b239 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,34 +4,34 @@ pluginManagement { jcenter() gradlePluginPortal() maven("https://dl.bintray.com/kotlin/kotlin-eap") - maven("https://dl.bintray.com/kotlin/kotlinx") - maven("https://dl.bintray.com/mipt-npm/scientifik") + maven("https://dl.bintray.com/kotlin/kotlin-dev") + maven("https://dl.bintray.com/mipt-npm/dataforge") + maven("https://dl.bintray.com/mipt-npm/kscience") maven("https://dl.bintray.com/mipt-npm/dev") } - resolutionStrategy { - eachPlugin { - when (requested.id.id) { - "kotlinx-atomicfu" -> useModule("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${requested.version}") - "scientifik.mpp", "scientifik.jvm", "scientifik.publish" -> useModule("scientifik:gradle-tools:${requested.version}") - } - } + + val toolsVersion = "0.7.0" + val kotlinVersion = "1.4.20" + + plugins { + id("ru.mipt.npm.project") version toolsVersion + id("ru.mipt.npm.mpp") version toolsVersion + id("ru.mipt.npm.jvm") version toolsVersion + id("ru.mipt.npm.js") version toolsVersion + id("ru.mipt.npm.publish") version toolsVersion + kotlin("jvm") version kotlinVersion + kotlin("js") version kotlinVersion } } -enableFeaturePreview("GRADLE_METADATA") - -//rootProject.name = "dataforge-core" include( ":dataforge-meta", ":dataforge-io", - ":dataforge-io:dataforge-io-yaml", +// ":dataforge-io:dataforge-io-yaml", ":dataforge-context", ":dataforge-data", - ":dataforge-output", - ":dataforge-output:dataforge-output-html", +// ":dataforge-output", ":dataforge-tables", ":dataforge-workspace", ":dataforge-scripting" -) - -//includeBuild("../kotlinx-io") \ No newline at end of file +) \ No newline at end of file