Explicit mode

This commit is contained in:
Alexander Nozik 2020-09-08 21:45:50 +03:00
parent 8a8484172c
commit 606faa5e1b
30 changed files with 251 additions and 258 deletions

View File

@ -11,9 +11,9 @@ import kotlinx.io.text.readUtf8Line
import kotlinx.io.text.writeUtf8String
@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 readPartial(input: Input): PartialEnvelope {
@ -80,8 +80,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()

View File

@ -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 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)
public operator fun Binary.get(range: IntRange): BinaryView = view(range.first, range.last - range.first)

View File

@ -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 operator fun <T : Any> get(
type: KClass<out T>,
name: Name,
stage: Name = Name.EMPTY,
@ -30,12 +30,12 @@ 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 operator fun <reified T : Any> OutputManager.get(
name: Name,
stage: Name = Name.EMPTY,
meta: Meta = Meta.EMPTY
@ -46,14 +46,14 @@ inline operator fun <reified T : Any> OutputManager.get(
/**
* Directly render an object using the most suitable renderer
*/
fun OutputManager.render(obj: Any, name: Name, stage: Name = Name.EMPTY, meta: Meta = Meta.EMPTY) =
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)
/**
* System console output.
* The [CONSOLE_RENDERER] is used when no other [OutputManager] is provided.
*/
val CONSOLE_RENDERER: Renderer<Any> = object : Renderer<Any> {
public val CONSOLE_RENDERER: Renderer<Any> = object : Renderer<Any> {
override fun render(obj: Any, meta: Meta) {
println(obj)
}
@ -62,21 +62,21 @@ val CONSOLE_RENDERER: Renderer<Any> = object : Renderer<Any> {
}
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
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
public expect val Dispatchers.Output: CoroutineDispatcher

View File

@ -10,12 +10,12 @@ import hep.dataforge.meta.Meta
* based on its configuration and provided meta
*
*/
interface Renderer<in T : Any> : ContextAware {
public interface Renderer<in T : Any> : ContextAware {
/**
* 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 = Meta.EMPTY)
}

View File

@ -11,7 +11,41 @@ import kotlinx.io.Output
import kotlinx.io.text.writeUtf8String
import kotlin.reflect.KClass
class TextRenderer(override val context: Context, private val output: Output) : Renderer<Any> {
/**
* A text or binary renderer based on [Output]
*/
@Type(TEXT_RENDERER_TYPE)
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 Output.render(obj: Any)
public companion object {
public const val TEXT_RENDERER_TYPE: String = "dataforge.textRenderer"
}
}
public 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")
}
}
/**
* A text-based renderer
*/
public class TextRenderer(override val context: Context, private val output: Output) : Renderer<Any> {
private val cache = HashMap<KClass<*>, TextFormat>()
/**
@ -39,34 +73,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")
}
}

View File

@ -4,4 +4,4 @@ import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
actual val Dispatchers.Output: CoroutineDispatcher get() = Dispatchers.Default
public actual val Dispatchers.Output: CoroutineDispatcher get() = Default

View File

@ -1,5 +1,6 @@
package hep.dataforge.output
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
actual val Dispatchers.Output get() = Dispatchers.IO
public actual val Dispatchers.Output: CoroutineDispatcher get() = IO

View File

@ -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

View File

@ -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

View File

@ -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)
}

View File

@ -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 {

View File

@ -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)
}

View File

@ -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)
}

View File

@ -4,37 +4,37 @@ import hep.dataforge.meta.Meta
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)
}

View File

@ -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)
public suspend fun <C : Any> Rows<C>.collect(): Table<C> = this as? Table<C> ?: RowTable(rowFlow().toList(), header)

View File

@ -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)
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)

View File

@ -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)
}

View File

@ -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
}

View File

@ -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,7 +32,7 @@ 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() }
.map { (_, item) ->

View File

@ -4,9 +4,9 @@ import hep.dataforge.meta.Meta
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 +34,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 +43,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 +73,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

View File

@ -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()) {
@ -33,29 +34,29 @@ class DataDependency(val filter: DataFilter, val placement: Name = Name.EMPTY) :
}
}
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

View File

@ -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)

View File

@ -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>,
@ -22,7 +22,7 @@ class SimpleWorkspace(
context.resolve<Task<*>>(Task.TYPE) + tasks.toMap()
}
companion object {
public companion object {
}
}

View File

@ -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 = "task"
}
}

View File

@ -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,

View File

@ -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 = "@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 ?: ""
public val TaskModel.target: String get() = meta[MODEL_TARGET_KEY]?.string ?: ""

View File

@ -15,21 +15,21 @@ 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> {
return when (target) {
@ -44,7 +44,7 @@ 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> {
public fun <R : Any> run(task: Task<R>, config: Meta): DataNode<R> {
context.activate(this)
try {
val model = task.build(this, config)
@ -55,27 +55,27 @@ interface Workspace : ContextAware, Provider {
}
}
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> {
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))

View File

@ -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 = {}) {
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()

View File

@ -9,9 +9,9 @@ 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> {
return when (target) {
@ -20,11 +20,11 @@ abstract class WorkspacePlugin : AbstractPlugin() {
}
}
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,7 +32,7 @@ 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)

View File

@ -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)