Fixed inline invloke
on Specification
This commit is contained in:
parent
920366388d
commit
0a77f729ec
@ -14,9 +14,11 @@
|
|||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
- Context activation API
|
- Context activation API
|
||||||
|
- TextRenderer
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Functional server prototype
|
- Functional server prototype
|
||||||
|
- `dataforge-output` module
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Global context CoroutineScope resolution
|
- Global context CoroutineScope resolution
|
||||||
|
@ -2,7 +2,7 @@ plugins {
|
|||||||
id("ru.mipt.npm.project")
|
id("ru.mipt.npm.project")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion by extra("0.2.0-dev-7")
|
val dataforgeVersion by extra("0.2.0-dev-8")
|
||||||
|
|
||||||
val bintrayRepo by extra("dataforge")
|
val bintrayRepo by extra("dataforge")
|
||||||
val githubProject by extra("dataforge-core")
|
val githubProject by extra("dataforge-core")
|
||||||
|
@ -18,10 +18,10 @@ public interface Specification<T : MutableItemProvider> {
|
|||||||
public fun wrap(meta: Meta, defaultProvider: ItemProvider = ItemProvider.EMPTY): T
|
public fun wrap(meta: Meta, defaultProvider: ItemProvider = ItemProvider.EMPTY): T
|
||||||
}
|
}
|
||||||
|
|
||||||
public operator fun <T : MutableItemProvider> Specification<T>.invoke(action: T.() -> Unit): T = empty().apply(action)
|
|
||||||
|
|
||||||
public fun <T : MutableItemProvider> Specification<T>.empty(): T = wrap(Config())
|
public fun <T : MutableItemProvider> Specification<T>.empty(): T = wrap(Config())
|
||||||
|
|
||||||
|
public inline operator fun <T : MutableItemProvider> Specification<T>.invoke(action: T.() -> Unit): T = empty().apply(action)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update given configuration using given type as a builder
|
* Update given configuration using given type as a builder
|
||||||
*/
|
*/
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
public final class hep/dataforge/output/html/DefaultHtmlBuilder : hep/dataforge/output/html/HtmlBuilder {
|
|
||||||
public static final field INSTANCE Lhep/dataforge/output/html/DefaultHtmlBuilder;
|
|
||||||
public fun getPriority ()I
|
|
||||||
public fun getType ()Lkotlin/reflect/KClass;
|
|
||||||
public fun render (Lkotlinx/html/FlowContent;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract interface class hep/dataforge/output/html/HtmlBuilder {
|
|
||||||
public static final field Companion Lhep/dataforge/output/html/HtmlBuilder$Companion;
|
|
||||||
public static final field HTML_CONVERTER_TYPE Ljava/lang/String;
|
|
||||||
public abstract fun getPriority ()I
|
|
||||||
public abstract fun getType ()Lkotlin/reflect/KClass;
|
|
||||||
public abstract fun render (Lkotlinx/html/FlowContent;Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class hep/dataforge/output/html/HtmlBuilder$Companion {
|
|
||||||
public static final field HTML_CONVERTER_TYPE Ljava/lang/String;
|
|
||||||
}
|
|
||||||
|
|
||||||
public final class hep/dataforge/output/html/HtmlRenderer : hep/dataforge/output/Renderer {
|
|
||||||
public fun <init> (Lhep/dataforge/context/Context;Lkotlinx/html/TagConsumer;)V
|
|
||||||
public fun getContext ()Lhep/dataforge/context/Context;
|
|
||||||
public fun getLogger ()Lmu/KLogger;
|
|
||||||
public fun render (Ljava/lang/Object;Lhep/dataforge/meta/Meta;)V
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id("ru.mipt.npm.mpp")
|
|
||||||
}
|
|
||||||
|
|
||||||
val htmlVersion by rootProject.extra("0.7.2")
|
|
||||||
|
|
||||||
kotlin {
|
|
||||||
sourceSets {
|
|
||||||
val commonMain by getting {
|
|
||||||
dependencies {
|
|
||||||
api(project(":dataforge-output"))
|
|
||||||
api("org.jetbrains.kotlinx:kotlinx-html:$htmlVersion")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
package hep.dataforge.output.html
|
|
||||||
|
|
||||||
import hep.dataforge.context.Context
|
|
||||||
import hep.dataforge.meta.DFExperimental
|
|
||||||
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.FlowContent
|
|
||||||
import kotlinx.html.TagConsumer
|
|
||||||
import kotlinx.html.p
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
|
|
||||||
@DFExperimental
|
|
||||||
public 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 { render(obj) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A text or binary renderer based on [Renderer]
|
|
||||||
*/
|
|
||||||
@Type(HTML_CONVERTER_TYPE)
|
|
||||||
public interface HtmlBuilder<T : Any> {
|
|
||||||
/**
|
|
||||||
* 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<T>
|
|
||||||
|
|
||||||
public suspend fun FlowContent.render(obj: T)
|
|
||||||
|
|
||||||
public companion object {
|
|
||||||
public const val HTML_CONVERTER_TYPE: String = "dataforge.htmlBuilder"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public object DefaultHtmlBuilder : HtmlBuilder<Any> {
|
|
||||||
override val priority: Int = Int.MAX_VALUE
|
|
||||||
override val type: KClass<Any> = Any::class
|
|
||||||
|
|
||||||
override suspend fun FlowContent.render(obj: Any) {
|
|
||||||
p { +obj.toString() }
|
|
||||||
}
|
|
||||||
}
|
|
@ -19,7 +19,7 @@ public interface OutputManager {
|
|||||||
* @param name represents the name inside the node.
|
* @param name represents the name inside the node.
|
||||||
* @param meta configuration for [Renderer] (not for rendered object)
|
* @param meta configuration for [Renderer] (not for rendered object)
|
||||||
*/
|
*/
|
||||||
public operator fun <T : Any> get(
|
public fun <T : Any> getOutputContainer(
|
||||||
type: KClass<out T>,
|
type: KClass<out T>,
|
||||||
name: Name,
|
name: Name,
|
||||||
stage: Name = Name.EMPTY,
|
stage: Name = Name.EMPTY,
|
||||||
@ -35,37 +35,30 @@ public val Context.output: OutputManager get() = plugins.get() ?: ConsoleOutputM
|
|||||||
/**
|
/**
|
||||||
* Get an output with given [name], [stage] and reified content type
|
* Get an output with given [name], [stage] and reified content type
|
||||||
*/
|
*/
|
||||||
public inline operator fun <reified T : Any> OutputManager.get(
|
public inline fun <reified T : Any> OutputManager.getOutputContainer(
|
||||||
name: Name,
|
name: Name,
|
||||||
stage: Name = Name.EMPTY,
|
stage: Name = Name.EMPTY,
|
||||||
meta: Meta = Meta.EMPTY
|
meta: Meta = Meta.EMPTY
|
||||||
): Renderer<T> {
|
): 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
|
* Directly render an object using the most suitable renderer
|
||||||
*/
|
*/
|
||||||
public fun OutputManager.render(obj: Any, name: Name, stage: Name = Name.EMPTY, meta: Meta = Meta.EMPTY): Unit =
|
public fun OutputManager.render(obj: Any, name: Name, stage: Name = Name.EMPTY, meta: Meta = Meta.EMPTY): Unit =
|
||||||
get(obj::class, name, stage).render(obj, meta)
|
getOutputContainer(obj::class, name, stage).render(obj, meta)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* System console output.
|
* System console output.
|
||||||
* The [CONSOLE_RENDERER] is used when no other [OutputManager] is provided.
|
* The [CONSOLE_RENDERER] is used when no other [OutputManager] is provided.
|
||||||
*/
|
*/
|
||||||
public val CONSOLE_RENDERER: Renderer<Any> = object : Renderer<Any> {
|
public val CONSOLE_RENDERER: Renderer<Any> = Renderer { obj, meta -> println(obj) }
|
||||||
override fun render(obj: Any, meta: Meta) {
|
|
||||||
println(obj)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val context: Context get() = Global
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ConsoleOutputManager : AbstractPlugin(), OutputManager {
|
public class ConsoleOutputManager : AbstractPlugin(), OutputManager {
|
||||||
override val tag: PluginTag get() = ConsoleOutputManager.tag
|
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
|
||||||
|
|
||||||
public companion object : PluginFactory<ConsoleOutputManager> {
|
public companion object : PluginFactory<ConsoleOutputManager> {
|
||||||
override val tag: PluginTag = PluginTag("output.console", group = DATAFORGE_GROUP)
|
override val tag: PluginTag = PluginTag("output.console", group = DATAFORGE_GROUP)
|
||||||
|
@ -10,12 +10,12 @@ import hep.dataforge.meta.Meta
|
|||||||
* based on its configuration and provided meta
|
* based on its configuration and provided meta
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface Renderer<in T : Any> : ContextAware {
|
public fun interface Renderer<in T : Any> {
|
||||||
/**
|
/**
|
||||||
* Render specific object with configuration.
|
* Render specific object with configuration.
|
||||||
*
|
*
|
||||||
* By convention actual render is called in asynchronous mode, so this method should never
|
* By convention actual render is called in asynchronous mode, so this method should never
|
||||||
* block execution
|
* block execution
|
||||||
*/
|
*/
|
||||||
public fun render(obj: T, meta: Meta = Meta.EMPTY)
|
public fun render(obj: T, meta: Meta)
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,14 @@ import hep.dataforge.provider.top
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A text or binary renderer based on [Output]
|
* A text or binary renderer based on [Output]
|
||||||
*/
|
*/
|
||||||
@Type(TEXT_RENDERER_TYPE)
|
@Type(TEXT_RENDERER_TYPE)
|
||||||
|
@Deprecated("Bad design")
|
||||||
public interface TextFormat {
|
public interface TextFormat {
|
||||||
/**
|
/**
|
||||||
* The priority of this renderer compared to other renderers
|
* The priority of this renderer compared to other renderers
|
||||||
@ -31,6 +33,7 @@ public interface TextFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Bad design")
|
||||||
public object DefaultTextFormat : TextFormat {
|
public object DefaultTextFormat : TextFormat {
|
||||||
override val priority: Int = Int.MAX_VALUE
|
override val priority: Int = Int.MAX_VALUE
|
||||||
override val type: KClass<*> = Any::class
|
override val type: KClass<*> = Any::class
|
||||||
@ -43,6 +46,7 @@ public object DefaultTextFormat : TextFormat {
|
|||||||
/**
|
/**
|
||||||
* A text-based renderer
|
* A text-based renderer
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Bad design")
|
||||||
public class TextRenderer(override val context: Context, private val output: Appendable) : Renderer<Any> {
|
public class TextRenderer(override val context: Context, private val output: Appendable) : Renderer<Any> {
|
||||||
private val cache = HashMap<KClass<*>, TextFormat>()
|
private val cache = HashMap<KClass<*>, TextFormat>()
|
||||||
|
|
||||||
|
@ -9,7 +9,6 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
api(project(":dataforge-context"))
|
api(project(":dataforge-context"))
|
||||||
api(project(":dataforge-data"))
|
api(project(":dataforge-data"))
|
||||||
api(project(":dataforge-output"))
|
|
||||||
api(project(":dataforge-io"))
|
api(project(":dataforge-io"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ private fun newZFS(path: Path): FileSystem {
|
|||||||
* @param metaFileFormat the meta format for override
|
* @param metaFileFormat the meta format for override
|
||||||
*/
|
*/
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun <T : Any> IOPlugin.readDataFile(
|
public fun <T : Any> IOPlugin.readDataFile(
|
||||||
path: Path,
|
path: Path,
|
||||||
type: KClass<out T>,
|
type: KClass<out T>,
|
||||||
formatResolver: FileFormatResolver<T>
|
formatResolver: FileFormatResolver<T>
|
||||||
@ -47,7 +47,7 @@ fun <T : Any> IOPlugin.readDataFile(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@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) { _, _ ->
|
readDataFile(path, T::class) { _, _ ->
|
||||||
resolveIOFormat<T>() ?: error("Can't resolve IO format for ${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
|
* Add file/directory-based data tree item
|
||||||
*/
|
*/
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun <T : Any> DataTreeBuilder<T>.file(
|
public fun <T : Any> DataTreeBuilder<T>.file(
|
||||||
plugin: IOPlugin,
|
plugin: IOPlugin,
|
||||||
path: Path,
|
path: Path,
|
||||||
formatResolver: FileFormatResolver<T>
|
formatResolver: FileFormatResolver<T>
|
||||||
@ -109,7 +109,7 @@ fun <T : Any> IOPlugin.readDataDirectory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@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) { _, _ ->
|
readDataDirectory(path, T::class) { _, _ ->
|
||||||
resolveIOFormat<T>() ?: error("Can't resolve IO format for ${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
|
* Write data tree to existing directory or create a new one using default [java.nio.file.FileSystem] provider
|
||||||
*/
|
*/
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
suspend fun <T : Any> IOPlugin.writeDataDirectory(
|
public suspend fun <T : Any> IOPlugin.writeDataDirectory(
|
||||||
path: Path,
|
path: Path,
|
||||||
node: DataNode<T>,
|
node: DataNode<T>,
|
||||||
format: IOFormat<T>,
|
format: IOFormat<T>,
|
||||||
|
@ -30,8 +30,7 @@ include(
|
|||||||
":dataforge-io:dataforge-io-yaml",
|
":dataforge-io:dataforge-io-yaml",
|
||||||
":dataforge-context",
|
":dataforge-context",
|
||||||
":dataforge-data",
|
":dataforge-data",
|
||||||
":dataforge-output",
|
// ":dataforge-output",
|
||||||
":dataforge-output:dataforge-output-html",
|
|
||||||
":dataforge-tables",
|
":dataforge-tables",
|
||||||
":dataforge-workspace",
|
":dataforge-workspace",
|
||||||
":dataforge-scripting"
|
":dataforge-scripting"
|
||||||
|
Loading…
Reference in New Issue
Block a user