Fixed inline invloke
on Specification
This commit is contained in:
parent
920366388d
commit
0a77f729ec
@ -14,9 +14,11 @@
|
||||
|
||||
### Deprecated
|
||||
- Context activation API
|
||||
- TextRenderer
|
||||
|
||||
### Removed
|
||||
- Functional server prototype
|
||||
- `dataforge-output` module
|
||||
|
||||
### Fixed
|
||||
- Global context CoroutineScope resolution
|
||||
|
@ -2,7 +2,7 @@ plugins {
|
||||
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 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 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 inline operator fun <T : MutableItemProvider> Specification<T>.invoke(action: T.() -> Unit): T = empty().apply(action)
|
||||
|
||||
/**
|
||||
* 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 meta configuration for [Renderer] (not for rendered object)
|
||||
*/
|
||||
public operator fun <T : Any> get(
|
||||
public fun <T : Any> getOutputContainer(
|
||||
type: KClass<out T>,
|
||||
name: Name,
|
||||
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
|
||||
*/
|
||||
public 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
|
||||
*/
|
||||
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.
|
||||
* The [CONSOLE_RENDERER] is used when no other [OutputManager] is provided.
|
||||
*/
|
||||
public val CONSOLE_RENDERER: Renderer<Any> = object : Renderer<Any> {
|
||||
override fun render(obj: Any, meta: Meta) {
|
||||
println(obj)
|
||||
}
|
||||
|
||||
override val context: Context get() = Global
|
||||
|
||||
}
|
||||
public val CONSOLE_RENDERER: Renderer<Any> = Renderer { obj, meta -> println(obj) }
|
||||
|
||||
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
|
||||
|
||||
public companion object : PluginFactory<ConsoleOutputManager> {
|
||||
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
|
||||
*
|
||||
*/
|
||||
public 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
|
||||
*/
|
||||
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.launch
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -31,6 +33,7 @@ public interface TextFormat {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated("Bad design")
|
||||
public object DefaultTextFormat : TextFormat {
|
||||
override val priority: Int = Int.MAX_VALUE
|
||||
override val type: KClass<*> = Any::class
|
||||
@ -43,6 +46,7 @@ public object DefaultTextFormat : TextFormat {
|
||||
/**
|
||||
* 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>()
|
||||
|
||||
|
@ -9,7 +9,6 @@ kotlin {
|
||||
dependencies {
|
||||
api(project(":dataforge-context"))
|
||||
api(project(":dataforge-data"))
|
||||
api(project(":dataforge-output"))
|
||||
api(project(":dataforge-io"))
|
||||
}
|
||||
}
|
||||
|
@ -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>,
|
||||
|
@ -30,8 +30,7 @@ include(
|
||||
":dataforge-io:dataforge-io-yaml",
|
||||
":dataforge-context",
|
||||
":dataforge-data",
|
||||
":dataforge-output",
|
||||
":dataforge-output:dataforge-output-html",
|
||||
// ":dataforge-output",
|
||||
":dataforge-tables",
|
||||
":dataforge-workspace",
|
||||
":dataforge-scripting"
|
||||
|
Loading…
Reference in New Issue
Block a user