Code cleanup
This commit is contained in:
parent
5dd40f0226
commit
4cafac1f1b
@ -7,7 +7,7 @@ description = "Context and provider definitions"
|
|||||||
val coroutinesVersion: String by rootProject.extra
|
val coroutinesVersion: String by rootProject.extra
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvm ()
|
jvm()
|
||||||
js()
|
js()
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
@ -11,7 +11,6 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import mu.KLogger
|
import mu.KLogger
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.reflect.KClass
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top.
|
* The local environment for anything being done in DataForge framework. Contexts are organized into tree structure with [Global] at the top.
|
||||||
@ -102,12 +101,11 @@ inline fun <reified T : Any> Context.list(target: String): Sequence<T> {
|
|||||||
/**
|
/**
|
||||||
* A global root context
|
* A global root context
|
||||||
*/
|
*/
|
||||||
expect object Global : Context{
|
expect object Global : Context {
|
||||||
fun getContext(name: String): Context
|
fun getContext(name: String): Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface for something that encapsulated in context
|
* The interface for something that encapsulated in context
|
||||||
*
|
*
|
||||||
|
@ -59,7 +59,8 @@ class PluginManager(override val context: Context) : ContextAware, Iterable<Plug
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
operator fun <T : Plugin> get(type: KClass<T>, recursive: Boolean = true): T? = get(recursive) { type.isInstance(it) } as T?
|
operator fun <T : Plugin> get(type: KClass<T>, recursive: Boolean = true): T? =
|
||||||
|
get(recursive) { type.isInstance(it) } as T?
|
||||||
|
|
||||||
inline fun <reified T : Plugin> get(recursive: Boolean = true): T? = get(T::class, recursive)
|
inline fun <reified T : Plugin> get(recursive: Boolean = true): T? = get(T::class, recursive)
|
||||||
|
|
||||||
|
@ -24,5 +24,6 @@ expect object PluginRepository {
|
|||||||
/**
|
/**
|
||||||
* Fetch specific plugin and instantiate it with given meta
|
* Fetch specific plugin and instantiate it with given meta
|
||||||
*/
|
*/
|
||||||
fun PluginRepository.fetch(tag: PluginTag, meta: Meta): Plugin = PluginRepository.list().find { it.tag.matches(tag) }?.build(meta)
|
fun PluginRepository.fetch(tag: PluginTag, meta: Meta): Plugin =
|
||||||
|
PluginRepository.list().find { it.tag.matches(tag) }?.build(meta)
|
||||||
?: error("Plugin with tag $tag not found in the repository")
|
?: error("Plugin with tag $tag not found in the repository")
|
@ -11,9 +11,9 @@ import hep.dataforge.meta.buildMeta
|
|||||||
* @author Alexander Nozik
|
* @author Alexander Nozik
|
||||||
*/
|
*/
|
||||||
data class PluginTag(
|
data class PluginTag(
|
||||||
val name: String,
|
val name: String,
|
||||||
val group: String = "",
|
val group: String = "",
|
||||||
val version: String = ""
|
val version: String = ""
|
||||||
) : MetaRepr {
|
) : MetaRepr {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,14 +5,14 @@ import mu.KLogger
|
|||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import kotlin.jvm.Synchronized
|
import kotlin.jvm.Synchronized
|
||||||
|
|
||||||
actual object Global: Context, JSContext("GLOBAL", null){
|
actual object Global : Context, JSContext("GLOBAL", null) {
|
||||||
/**
|
/**
|
||||||
* Closing all contexts
|
* Closing all contexts
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
override fun close() {
|
override fun close() {
|
||||||
logger.info{"Shutting down GLOBAL"}
|
logger.info { "Shutting down GLOBAL" }
|
||||||
for (ctx in contextRegistry.values) {
|
for (ctx in contextRegistry.values) {
|
||||||
ctx.close()
|
ctx.close()
|
||||||
}
|
}
|
||||||
@ -34,10 +34,10 @@ actual object Global: Context, JSContext("GLOBAL", null){
|
|||||||
}
|
}
|
||||||
|
|
||||||
open class JSContext(
|
open class JSContext(
|
||||||
final override val name: String,
|
final override val name: String,
|
||||||
final override val parent: JSContext? = Global,
|
final override val parent: JSContext? = Global,
|
||||||
properties: Meta = EmptyMeta
|
properties: Meta = EmptyMeta
|
||||||
): Context {
|
) : Context {
|
||||||
|
|
||||||
private val _properties = Config().apply { update(properties) }
|
private val _properties = Config().apply { update(properties) }
|
||||||
override val properties: Meta
|
override val properties: Meta
|
||||||
|
@ -24,7 +24,7 @@ actual object PluginRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : Plugin> register(tag: PluginTag, noinline constructor: (Meta) -> T) =
|
inline fun <reified T : Plugin> register(tag: PluginTag, noinline constructor: (Meta) -> T) =
|
||||||
register(tag, T::class, constructor)
|
register(tag, T::class, constructor)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List plugins available in the repository
|
* List plugins available in the repository
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
package hep.dataforge.context
|
package hep.dataforge.context
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import mu.KLogger
|
import mu.KLogger
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
@ -24,15 +23,14 @@ import java.util.*
|
|||||||
import java.util.concurrent.ExecutorService
|
import java.util.concurrent.ExecutorService
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import kotlin.collections.HashSet
|
import kotlin.collections.HashSet
|
||||||
import kotlin.coroutines.CoroutineContext
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.full.cast
|
import kotlin.reflect.full.cast
|
||||||
|
|
||||||
open class JVMContext(
|
open class JVMContext(
|
||||||
final override val name: String,
|
final override val name: String,
|
||||||
final override val parent: JVMContext? = Global,
|
final override val parent: JVMContext? = Global,
|
||||||
classLoader: ClassLoader? = null,
|
classLoader: ClassLoader? = null,
|
||||||
properties: Meta = EmptyMeta
|
properties: Meta = EmptyMeta
|
||||||
) : Context, AutoCloseable {
|
) : Context, AutoCloseable {
|
||||||
|
|
||||||
private val _properties = Config().apply { update(properties) }
|
private val _properties = Config().apply { update(properties) }
|
||||||
@ -75,7 +73,8 @@ open class JVMContext(
|
|||||||
private val serviceCache: MutableMap<Class<*>, ServiceLoader<*>> = HashMap()
|
private val serviceCache: MutableMap<Class<*>, ServiceLoader<*>> = HashMap()
|
||||||
|
|
||||||
fun <T : Any> services(type: KClass<T>): Sequence<T> {
|
fun <T : Any> services(type: KClass<T>): Sequence<T> {
|
||||||
return serviceCache.getOrPut(type.java) { ServiceLoader.load(type.java, classLoader) }.asSequence().map { type.cast(it) }
|
return serviceCache.getOrPut(type.java) { ServiceLoader.load(type.java, classLoader) }.asSequence()
|
||||||
|
.map { type.cast(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,6 +12,6 @@ actual object PluginRepository {
|
|||||||
* List plugins available in the repository
|
* List plugins available in the repository
|
||||||
*/
|
*/
|
||||||
actual fun list(): Sequence<PluginFactory> =
|
actual fun list(): Sequence<PluginFactory> =
|
||||||
factories.asSequence() + Global.services(PluginFactory::class)
|
factories.asSequence() + Global.services(PluginFactory::class)
|
||||||
|
|
||||||
}
|
}
|
@ -50,10 +50,11 @@ class PipeAction<in T : Any, out R : Any>(val transform: (Name, Data<T>, Meta) -
|
|||||||
/**
|
/**
|
||||||
* A simple pipe that performs transformation on the data and copies input meta into the output
|
* A simple pipe that performs transformation on the data and copies input meta into the output
|
||||||
*/
|
*/
|
||||||
inline fun <T : Any, reified R : Any> simple(noinline transform: suspend (Name, T, Meta) -> R) = PipeAction { name, data: Data<T>, meta ->
|
inline fun <T : Any, reified R : Any> simple(noinline transform: suspend (Name, T, Meta) -> R) =
|
||||||
val goal = data.goal.pipe { transform(name, it, meta) }
|
PipeAction { name, data: Data<T>, meta ->
|
||||||
return@PipeAction Data.of(goal, data.meta)
|
val goal = data.goal.pipe { transform(name, it, meta) }
|
||||||
}
|
return@PipeAction Data.of(goal, data.meta)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@ interface Goal<out T> : Deferred<T>, CoroutineScope {
|
|||||||
/**
|
/**
|
||||||
* Create goal wrapping static value. This goal is always completed
|
* Create goal wrapping static value. This goal is always completed
|
||||||
*/
|
*/
|
||||||
fun <T> static(context: CoroutineContext, value: T): Goal<T> = StaticGoalImpl(context, CompletableDeferred(value))
|
fun <T> static(context: CoroutineContext, value: T): Goal<T> =
|
||||||
|
StaticGoalImpl(context, CompletableDeferred(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,16 +49,18 @@ class GoalMonitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class GoalImpl<T>(
|
private class GoalImpl<T>(
|
||||||
override val dependencies: Collection<Goal<*>>,
|
override val dependencies: Collection<Goal<*>>,
|
||||||
val monitor: GoalMonitor,
|
val monitor: GoalMonitor,
|
||||||
deferred: Deferred<T>) : Goal<T>, Deferred<T> by deferred {
|
deferred: Deferred<T>
|
||||||
|
) : Goal<T>, Deferred<T> by deferred {
|
||||||
override val coroutineContext: CoroutineContext get() = this
|
override val coroutineContext: CoroutineContext get() = this
|
||||||
override val totalWork: Double get() = dependencies.sumByDouble { totalWork } + monitor.totalWork
|
override val totalWork: Double get() = dependencies.sumByDouble { totalWork } + monitor.totalWork
|
||||||
override val workDone: Double get() = dependencies.sumByDouble { workDone } + monitor.workDone
|
override val workDone: Double get() = dependencies.sumByDouble { workDone } + monitor.workDone
|
||||||
override val status: String get() = monitor.status
|
override val status: String get() = monitor.status
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StaticGoalImpl<T>(val context: CoroutineContext, deferred: CompletableDeferred<T>) : Goal<T>, Deferred<T> by deferred {
|
private class StaticGoalImpl<T>(val context: CoroutineContext, deferred: CompletableDeferred<T>) : Goal<T>,
|
||||||
|
Deferred<T> by deferred {
|
||||||
override val dependencies: Collection<Goal<*>> get() = emptyList()
|
override val dependencies: Collection<Goal<*>> get() = emptyList()
|
||||||
override val status: String get() = ""
|
override val status: String get() = ""
|
||||||
override val totalWork: Double get() = 0.0
|
override val totalWork: Double get() = 0.0
|
||||||
@ -94,7 +97,10 @@ fun <T, R> Goal<T>.pipe(block: suspend GoalMonitor.(T) -> R): Goal<R> = createGo
|
|||||||
* Create a joining goal.
|
* Create a joining goal.
|
||||||
* @param scope the scope for resulting goal. By default use first goal in list
|
* @param scope the scope for resulting goal. By default use first goal in list
|
||||||
*/
|
*/
|
||||||
fun <T, R> Collection<Goal<T>>.join(scope: CoroutineScope = first(), block: suspend GoalMonitor.(Collection<T>) -> R): Goal<R> =
|
fun <T, R> Collection<Goal<T>>.join(
|
||||||
scope.createGoal(this) {
|
scope: CoroutineScope = first(),
|
||||||
block(map { it.await() })
|
block: suspend GoalMonitor.(Collection<T>) -> R
|
||||||
}
|
): Goal<R> =
|
||||||
|
scope.createGoal(this) {
|
||||||
|
block(map { it.await() })
|
||||||
|
}
|
@ -31,6 +31,10 @@ interface OutputManager : Plugin {
|
|||||||
/**
|
/**
|
||||||
* Get an output with given [name], [stage] and reified content type
|
* Get an output with given [name], [stage] and reified content type
|
||||||
*/
|
*/
|
||||||
inline fun <reified T : Any> OutputManager.typed(name: Name, stage: Name = EmptyName, meta: Meta = EmptyMeta): Output<T> {
|
inline fun <reified T : Any> OutputManager.typed(
|
||||||
|
name: Name,
|
||||||
|
stage: Name = EmptyName,
|
||||||
|
meta: Meta = EmptyMeta
|
||||||
|
): Output<T> {
|
||||||
return typed(T::class, name, stage, meta)
|
return typed(T::class, name, stage, meta)
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ object BinaryMetaFormat : MetaFormat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BinaryMetaFormatFactory: MetaFormatFactory{
|
class BinaryMetaFormatFactory : MetaFormatFactory {
|
||||||
override val name: String = "bin"
|
override val name: String = "bin"
|
||||||
override val key: Short = 0x4249//BI
|
override val key: Short = 0x4249//BI
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ class JsonMeta(val json: JsonObject) : Meta {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class JsonMetaFormatFactory: MetaFormatFactory{
|
class JsonMetaFormatFactory : MetaFormatFactory {
|
||||||
override val name: String = "json"
|
override val name: String = "json"
|
||||||
override val key: Short = 0x4a53//"JS"
|
override val key: Short = 0x4a53//"JS"
|
||||||
|
|
||||||
|
@ -21,13 +21,13 @@ interface MetaFormatFactory {
|
|||||||
fun build(): MetaFormat
|
fun build(): MetaFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Meta.asString(format: MetaFormat = JsonMetaFormat): String{
|
fun Meta.asString(format: MetaFormat = JsonMetaFormat): String {
|
||||||
val builder = BytePacketBuilder()
|
val builder = BytePacketBuilder()
|
||||||
format.write(this,builder)
|
format.write(this, builder)
|
||||||
return builder.build().readText()
|
return builder.build().readText()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MetaFormat.parse(str: String): Meta{
|
fun MetaFormat.parse(str: String): Meta {
|
||||||
return read(ByteReadPacket(str.toByteArray()))
|
return read(ByteReadPacket(str.toByteArray()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@ import hep.dataforge.meta.buildMeta
|
|||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class MetaFormatTest{
|
class MetaFormatTest {
|
||||||
@Test
|
@Test
|
||||||
fun testBinaryMetaFormat(){
|
fun testBinaryMetaFormat() {
|
||||||
val meta = buildMeta {
|
val meta = buildMeta {
|
||||||
"a" to 22
|
"a" to 22
|
||||||
"node" to {
|
"node" to {
|
||||||
@ -14,13 +14,13 @@ class MetaFormatTest{
|
|||||||
"c" to 11.1
|
"c" to 11.1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val string = meta.asString(BinaryMetaFormat)
|
val string = meta.asString(BinaryMetaFormat)
|
||||||
val result = BinaryMetaFormat.parse(string)
|
val result = BinaryMetaFormat.parse(string)
|
||||||
assertEquals(meta, result)
|
assertEquals(meta, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testJsonMetaFormat(){
|
fun testJsonMetaFormat() {
|
||||||
val meta = buildMeta {
|
val meta = buildMeta {
|
||||||
"a" to 22
|
"a" to 22
|
||||||
"node" to {
|
"node" to {
|
||||||
@ -30,7 +30,7 @@ class MetaFormatTest{
|
|||||||
}
|
}
|
||||||
val string = meta.asString(JsonMetaFormat)
|
val string = meta.asString(JsonMetaFormat)
|
||||||
val result = JsonMetaFormat.parse(string)
|
val result = JsonMetaFormat.parse(string)
|
||||||
assertEquals(meta,result)
|
assertEquals(meta, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -11,25 +11,29 @@ import kotlin.reflect.KProperty
|
|||||||
|
|
||||||
//TODO add caching for sealed nodes
|
//TODO add caching for sealed nodes
|
||||||
|
|
||||||
class ValueDelegate(private val key: String? = null, private val default: Value? = null) : ReadOnlyProperty<Metoid, Value?> {
|
class ValueDelegate(private val key: String? = null, private val default: Value? = null) :
|
||||||
|
ReadOnlyProperty<Metoid, Value?> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Value? {
|
override fun getValue(thisRef: Metoid, property: KProperty<*>): Value? {
|
||||||
return thisRef.meta[key ?: property.name]?.value ?: default
|
return thisRef.meta[key ?: property.name]?.value ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringDelegate(private val key: String? = null, private val default: String? = null) : ReadOnlyProperty<Metoid, String?> {
|
class StringDelegate(private val key: String? = null, private val default: String? = null) :
|
||||||
|
ReadOnlyProperty<Metoid, String?> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): String? {
|
override fun getValue(thisRef: Metoid, property: KProperty<*>): String? {
|
||||||
return thisRef.meta[key ?: property.name]?.string ?: default
|
return thisRef.meta[key ?: property.name]?.string ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BooleanDelegate(private val key: String? = null, private val default: Boolean? = null) : ReadOnlyProperty<Metoid, Boolean?> {
|
class BooleanDelegate(private val key: String? = null, private val default: Boolean? = null) :
|
||||||
|
ReadOnlyProperty<Metoid, Boolean?> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Boolean? {
|
override fun getValue(thisRef: Metoid, property: KProperty<*>): Boolean? {
|
||||||
return thisRef.meta[key ?: property.name]?.boolean ?: default
|
return thisRef.meta[key ?: property.name]?.boolean ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NumberDelegate(private val key: String? = null, private val default: Number? = null) : ReadOnlyProperty<Metoid, Number?> {
|
class NumberDelegate(private val key: String? = null, private val default: Number? = null) :
|
||||||
|
ReadOnlyProperty<Metoid, Number?> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Number? {
|
override fun getValue(thisRef: Metoid, property: KProperty<*>): Number? {
|
||||||
return thisRef.meta[key ?: property.name]?.number ?: default
|
return thisRef.meta[key ?: property.name]?.number ?: default
|
||||||
}
|
}
|
||||||
@ -37,25 +41,32 @@ class NumberDelegate(private val key: String? = null, private val default: Numbe
|
|||||||
|
|
||||||
//Delegates with non-null values
|
//Delegates with non-null values
|
||||||
|
|
||||||
class SafeStringDelegate(private val key: String? = null, private val default: String) : ReadOnlyProperty<Metoid, String> {
|
class SafeStringDelegate(private val key: String? = null, private val default: String) :
|
||||||
|
ReadOnlyProperty<Metoid, String> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): String {
|
override fun getValue(thisRef: Metoid, property: KProperty<*>): String {
|
||||||
return thisRef.meta[key ?: property.name]?.string ?: default
|
return thisRef.meta[key ?: property.name]?.string ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeBooleanDelegate(private val key: String? = null, private val default: Boolean) : ReadOnlyProperty<Metoid, Boolean> {
|
class SafeBooleanDelegate(private val key: String? = null, private val default: Boolean) :
|
||||||
|
ReadOnlyProperty<Metoid, Boolean> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Boolean {
|
override fun getValue(thisRef: Metoid, property: KProperty<*>): Boolean {
|
||||||
return thisRef.meta[key ?: property.name]?.boolean ?: default
|
return thisRef.meta[key ?: property.name]?.boolean ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeNumberDelegate(private val key: String? = null, private val default: Number) : ReadOnlyProperty<Metoid, Number> {
|
class SafeNumberDelegate(private val key: String? = null, private val default: Number) :
|
||||||
|
ReadOnlyProperty<Metoid, Number> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Number {
|
override fun getValue(thisRef: Metoid, property: KProperty<*>): Number {
|
||||||
return thisRef.meta[key ?: property.name]?.number ?: default
|
return thisRef.meta[key ?: property.name]?.number ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeEnumDelegate<E : Enum<E>>(private val key: String? = null, private val default: E, private val resolver: (String) -> E) : ReadOnlyProperty<Metoid, E> {
|
class SafeEnumDelegate<E : Enum<E>>(
|
||||||
|
private val key: String? = null,
|
||||||
|
private val default: E,
|
||||||
|
private val resolver: (String) -> E
|
||||||
|
) : ReadOnlyProperty<Metoid, E> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): E {
|
override fun getValue(thisRef: Metoid, property: KProperty<*>): E {
|
||||||
return (thisRef.meta[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
return (thisRef.meta[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
||||||
}
|
}
|
||||||
@ -63,9 +74,10 @@ class SafeEnumDelegate<E : Enum<E>>(private val key: String? = null, private val
|
|||||||
|
|
||||||
//Child node delegate
|
//Child node delegate
|
||||||
|
|
||||||
class ChildDelegate<T>(private val key: String? = null, private val converter: (Meta) -> T) : ReadOnlyProperty<Metoid, T?> {
|
class ChildDelegate<T>(private val key: String? = null, private val converter: (Meta) -> T) :
|
||||||
|
ReadOnlyProperty<Metoid, T?> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): T? {
|
override fun getValue(thisRef: Metoid, property: KProperty<*>): T? {
|
||||||
return thisRef.meta[key ?: property.name]?.node?.let { converter(it)}
|
return thisRef.meta[key ?: property.name]?.node?.let { converter(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,18 +107,20 @@ fun Metoid.boolean(default: Boolean, key: String? = null) = SafeBooleanDelegate(
|
|||||||
@JvmName("safeNumber")
|
@JvmName("safeNumber")
|
||||||
fun Metoid.number(default: Number, key: String? = null) = SafeNumberDelegate(key, default)
|
fun Metoid.number(default: Number, key: String? = null) = SafeNumberDelegate(key, default)
|
||||||
|
|
||||||
inline fun <reified E : Enum<E>> Metoid.enum(default: E, key: String? = null) = SafeEnumDelegate(key, default) { enumValueOf(it) }
|
inline fun <reified E : Enum<E>> Metoid.enum(default: E, key: String? = null) =
|
||||||
|
SafeEnumDelegate(key, default) { enumValueOf(it) }
|
||||||
|
|
||||||
/* Config delegates */
|
/* Config delegates */
|
||||||
|
|
||||||
class ValueConfigDelegate(private val key: String? = null, private val default: Value? = null) : ReadWriteProperty<Configurable, Value?> {
|
class ValueConfigDelegate(private val key: String? = null, private val default: Value? = null) :
|
||||||
|
ReadWriteProperty<Configurable, Value?> {
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Value? {
|
override fun getValue(thisRef: Configurable, property: KProperty<*>): Value? {
|
||||||
return thisRef.config[key ?: property.name]?.value ?: default
|
return thisRef.config[key ?: property.name]?.value ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: Value?) {
|
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: Value?) {
|
||||||
val name = key ?: property.name
|
val name = key ?: property.name
|
||||||
if(value == null){
|
if (value == null) {
|
||||||
thisRef.config.remove(name)
|
thisRef.config.remove(name)
|
||||||
} else {
|
} else {
|
||||||
thisRef.config[name] = value
|
thisRef.config[name] = value
|
||||||
@ -114,7 +128,8 @@ class ValueConfigDelegate(private val key: String? = null, private val default:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringConfigDelegate(private val key: String? = null, private val default: String? = null) : ReadWriteProperty<Configurable, String?> {
|
class StringConfigDelegate(private val key: String? = null, private val default: String? = null) :
|
||||||
|
ReadWriteProperty<Configurable, String?> {
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): String? {
|
override fun getValue(thisRef: Configurable, property: KProperty<*>): String? {
|
||||||
return thisRef.config[key ?: property.name]?.string ?: default
|
return thisRef.config[key ?: property.name]?.string ?: default
|
||||||
}
|
}
|
||||||
@ -124,7 +139,8 @@ class StringConfigDelegate(private val key: String? = null, private val default:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BooleanConfigDelegate(private val key: String? = null, private val default: Boolean? = null) : ReadWriteProperty<Configurable, Boolean?> {
|
class BooleanConfigDelegate(private val key: String? = null, private val default: Boolean? = null) :
|
||||||
|
ReadWriteProperty<Configurable, Boolean?> {
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Boolean? {
|
override fun getValue(thisRef: Configurable, property: KProperty<*>): Boolean? {
|
||||||
return thisRef.config[key ?: property.name]?.boolean ?: default
|
return thisRef.config[key ?: property.name]?.boolean ?: default
|
||||||
}
|
}
|
||||||
@ -134,7 +150,8 @@ class BooleanConfigDelegate(private val key: String? = null, private val default
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NumberConfigDelegate(private val key: String? = null, private val default: Number? = null) : ReadWriteProperty<Configurable, Number?> {
|
class NumberConfigDelegate(private val key: String? = null, private val default: Number? = null) :
|
||||||
|
ReadWriteProperty<Configurable, Number?> {
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Number? {
|
override fun getValue(thisRef: Configurable, property: KProperty<*>): Number? {
|
||||||
return thisRef.config[key ?: property.name]?.number ?: default
|
return thisRef.config[key ?: property.name]?.number ?: default
|
||||||
}
|
}
|
||||||
@ -146,7 +163,8 @@ class NumberConfigDelegate(private val key: String? = null, private val default:
|
|||||||
|
|
||||||
//Delegates with non-null values
|
//Delegates with non-null values
|
||||||
|
|
||||||
class SafeStringConfigDelegate(private val key: String? = null, private val default: String) : ReadWriteProperty<Configurable, String> {
|
class SafeStringConfigDelegate(private val key: String? = null, private val default: String) :
|
||||||
|
ReadWriteProperty<Configurable, String> {
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): String {
|
override fun getValue(thisRef: Configurable, property: KProperty<*>): String {
|
||||||
return thisRef.config[key ?: property.name]?.string ?: default
|
return thisRef.config[key ?: property.name]?.string ?: default
|
||||||
}
|
}
|
||||||
@ -156,7 +174,8 @@ class SafeStringConfigDelegate(private val key: String? = null, private val defa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeBooleanConfigDelegate(private val key: String? = null, private val default: Boolean) : ReadWriteProperty<Configurable, Boolean> {
|
class SafeBooleanConfigDelegate(private val key: String? = null, private val default: Boolean) :
|
||||||
|
ReadWriteProperty<Configurable, Boolean> {
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Boolean {
|
override fun getValue(thisRef: Configurable, property: KProperty<*>): Boolean {
|
||||||
return thisRef.config[key ?: property.name]?.boolean ?: default
|
return thisRef.config[key ?: property.name]?.boolean ?: default
|
||||||
}
|
}
|
||||||
@ -166,7 +185,8 @@ class SafeBooleanConfigDelegate(private val key: String? = null, private val def
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeNumberConfigDelegate(private val key: String? = null, private val default: Number) : ReadWriteProperty<Configurable, Number> {
|
class SafeNumberConfigDelegate(private val key: String? = null, private val default: Number) :
|
||||||
|
ReadWriteProperty<Configurable, Number> {
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Number {
|
override fun getValue(thisRef: Configurable, property: KProperty<*>): Number {
|
||||||
return thisRef.config[key ?: property.name]?.number ?: default
|
return thisRef.config[key ?: property.name]?.number ?: default
|
||||||
}
|
}
|
||||||
@ -176,7 +196,11 @@ class SafeNumberConfigDelegate(private val key: String? = null, private val defa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeEnumvConfigDelegate<E : Enum<E>>(private val key: String? = null, private val default: E, private val resolver: (String) -> E) : ReadWriteProperty<Configurable, E> {
|
class SafeEnumvConfigDelegate<E : Enum<E>>(
|
||||||
|
private val key: String? = null,
|
||||||
|
private val default: E,
|
||||||
|
private val resolver: (String) -> E
|
||||||
|
) : ReadWriteProperty<Configurable, E> {
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): E {
|
override fun getValue(thisRef: Configurable, property: KProperty<*>): E {
|
||||||
return (thisRef.config[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
return (thisRef.config[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
||||||
}
|
}
|
||||||
@ -188,7 +212,8 @@ class SafeEnumvConfigDelegate<E : Enum<E>>(private val key: String? = null, priv
|
|||||||
|
|
||||||
//Child node delegate
|
//Child node delegate
|
||||||
|
|
||||||
class ChildConfigDelegate<T : Configurable>(private val key: String? = null, private val converter: (Config) -> T) : ReadWriteProperty<Configurable, T> {
|
class ChildConfigDelegate<T : Configurable>(private val key: String? = null, private val converter: (Config) -> T) :
|
||||||
|
ReadWriteProperty<Configurable, T> {
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): T {
|
override fun getValue(thisRef: Configurable, property: KProperty<*>): T {
|
||||||
return converter(thisRef.config[key ?: property.name]?.node ?: Config())
|
return converter(thisRef.config[key ?: property.name]?.node ?: Config())
|
||||||
}
|
}
|
||||||
@ -214,7 +239,8 @@ fun Configurable.number(default: Number? = null, key: String? = null) = NumberCo
|
|||||||
|
|
||||||
fun Configurable.child(key: String? = null) = ChildConfigDelegate(key) { SimpleConfigurable(it) }
|
fun Configurable.child(key: String? = null) = ChildConfigDelegate(key) { SimpleConfigurable(it) }
|
||||||
|
|
||||||
fun <T : Configurable> Configurable.child(key: String? = null, converter: (Config) -> T) = ChildConfigDelegate(key, converter)
|
fun <T : Configurable> Configurable.child(key: String? = null, converter: (Config) -> T) =
|
||||||
|
ChildConfigDelegate(key, converter)
|
||||||
|
|
||||||
//fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: String? = null) = ChildConfigDelegate<T>(key) { spec.wrap(this) }
|
//fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: String? = null) = ChildConfigDelegate<T>(key) { spec.wrap(this) }
|
||||||
|
|
||||||
@ -227,4 +253,5 @@ fun Configurable.boolean(default: Boolean, key: String? = null) = SafeBooleanCon
|
|||||||
@JvmName("safeNumber")
|
@JvmName("safeNumber")
|
||||||
fun Configurable.number(default: Number, key: String? = null) = SafeNumberConfigDelegate(key, default)
|
fun Configurable.number(default: Number, key: String? = null) = SafeNumberConfigDelegate(key, default)
|
||||||
|
|
||||||
inline fun <reified E : Enum<E>> Configurable.enum(default: E, key: String? = null) = SafeEnumvConfigDelegate(key, default) { enumValueOf(it) }
|
inline fun <reified E : Enum<E>> Configurable.enum(default: E, key: String? = null) =
|
||||||
|
SafeEnumvConfigDelegate(key, default) { enumValueOf(it) }
|
@ -10,14 +10,14 @@ import hep.dataforge.names.NameToken
|
|||||||
class Laminate(layers: List<Meta>) : Meta {
|
class Laminate(layers: List<Meta>) : Meta {
|
||||||
|
|
||||||
val layers: List<Meta> = layers.flatMap {
|
val layers: List<Meta> = layers.flatMap {
|
||||||
if(it is Laminate){
|
if (it is Laminate) {
|
||||||
it.layers
|
it.layers
|
||||||
} else{
|
} else {
|
||||||
listOf(it)
|
listOf(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(vararg layers: Meta): this(layers.asList())
|
constructor(vararg layers: Meta) : this(layers.asList())
|
||||||
|
|
||||||
override val items: Map<NameToken, MetaItem<out Meta>>
|
override val items: Map<NameToken, MetaItem<out Meta>>
|
||||||
get() = layers.map { it.items.keys }.flatten().associateWith { key ->
|
get() = layers.map { it.items.keys }.flatten().associateWith { key ->
|
||||||
|
@ -77,9 +77,9 @@ fun Meta.getAll(name: Name): Map<String, MetaItem<out Meta>> {
|
|||||||
val (body, query) = name.last()!!
|
val (body, query) = name.last()!!
|
||||||
val regex = query.toRegex()
|
val regex = query.toRegex()
|
||||||
return (this[name.cutLast()] as? NodeItem<*>)?.node?.items
|
return (this[name.cutLast()] as? NodeItem<*>)?.node?.items
|
||||||
?.filter { it.key.body == body && (query.isEmpty() || regex.matches(it.key.query)) }
|
?.filter { it.key.body == body && (query.isEmpty() || regex.matches(it.key.query)) }
|
||||||
?.mapKeys { it.key.query }
|
?.mapKeys { it.key.query }
|
||||||
?: emptyMap()
|
?: emptyMap()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,8 +155,8 @@ object EmptyMeta : Meta {
|
|||||||
|
|
||||||
val MetaItem<*>.value
|
val MetaItem<*>.value
|
||||||
get() = (this as? MetaItem.ValueItem)?.value
|
get() = (this as? MetaItem.ValueItem)?.value
|
||||||
?: (this.node[VALUE_KEY] as? MetaItem.ValueItem)?.value
|
?: (this.node[VALUE_KEY] as? MetaItem.ValueItem)?.value
|
||||||
?: error("Trying to interpret node meta item as value item")
|
?: error("Trying to interpret node meta item as value item")
|
||||||
val MetaItem<*>.string get() = value.string
|
val MetaItem<*>.string get() = value.string
|
||||||
val MetaItem<*>.boolean get() = value.boolean
|
val MetaItem<*>.boolean get() = value.boolean
|
||||||
val MetaItem<*>.number get() = value.number
|
val MetaItem<*>.number get() = value.number
|
||||||
|
@ -6,7 +6,10 @@ import hep.dataforge.names.plus
|
|||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
|
|
||||||
class MetaListener(val owner: Any? = null, val action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit) {
|
class MetaListener(
|
||||||
|
val owner: Any? = null,
|
||||||
|
val action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit
|
||||||
|
) {
|
||||||
operator fun invoke(name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) = action(name, oldItem, newItem)
|
operator fun invoke(name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) = action(name, oldItem, newItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +90,7 @@ abstract class MutableMetaNode<M : MutableMetaNode<M>> : MetaNode<M>(), MutableM
|
|||||||
val token = name.first()!!
|
val token = name.first()!!
|
||||||
//get existing or create new node. Query is ignored for new node
|
//get existing or create new node. Query is ignored for new node
|
||||||
val child = this.items[token]?.node
|
val child = this.items[token]?.node
|
||||||
?: empty().also { this[token.body.toName()] = MetaItem.NodeItem(it) }
|
?: empty().also { this[token.body.toName()] = MetaItem.NodeItem(it) }
|
||||||
child[name.cutFirst()] = item
|
child[name.cutFirst()] = item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,16 +133,20 @@ fun <M : MutableMetaNode<M>> M.update(meta: Meta) {
|
|||||||
meta.items.forEach { entry ->
|
meta.items.forEach { entry ->
|
||||||
val value = entry.value
|
val value = entry.value
|
||||||
when (value) {
|
when (value) {
|
||||||
is MetaItem.ValueItem -> setValue(entry.key.toName(),value.value)
|
is MetaItem.ValueItem -> setValue(entry.key.toName(), value.value)
|
||||||
is MetaItem.NodeItem -> (this[entry.key.toName()] as? MetaItem.NodeItem)?.node?.update(value.node)
|
is MetaItem.NodeItem -> (this[entry.key.toName()] as? MetaItem.NodeItem)?.node?.update(value.node)
|
||||||
?: run { setNode(entry.key.toName(),value.node)}
|
?: run { setNode(entry.key.toName(), value.node) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same name siblings generation */
|
/* Same name siblings generation */
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> M.setIndexed(name: Name, items: Iterable<MetaItem<M>>, queryFactory: (Int) -> String = { it.toString() }) {
|
fun <M : MutableMeta<M>> M.setIndexed(
|
||||||
|
name: Name,
|
||||||
|
items: Iterable<MetaItem<M>>,
|
||||||
|
queryFactory: (Int) -> String = { it.toString() }
|
||||||
|
) {
|
||||||
val tokens = name.tokens.toMutableList()
|
val tokens = name.tokens.toMutableList()
|
||||||
val last = tokens.last()
|
val last = tokens.last()
|
||||||
items.forEachIndexed { index, meta ->
|
items.forEachIndexed { index, meta ->
|
||||||
@ -149,7 +156,11 @@ fun <M : MutableMeta<M>> M.setIndexed(name: Name, items: Iterable<MetaItem<M>>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <M : MutableMetaNode<M>> M.setIndexed(name: Name, metas: Iterable<Meta>, queryFactory: (Int) -> String = { it.toString() }) {
|
fun <M : MutableMetaNode<M>> M.setIndexed(
|
||||||
|
name: Name,
|
||||||
|
metas: Iterable<Meta>,
|
||||||
|
queryFactory: (Int) -> String = { it.toString() }
|
||||||
|
) {
|
||||||
setIndexed(name, metas.map { wrap(name, it) }, queryFactory)
|
setIndexed(name, metas.map { wrap(name, it) }, queryFactory)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package hep.dataforge.meta
|
|||||||
/**
|
/**
|
||||||
* Marker interface for specifications
|
* Marker interface for specifications
|
||||||
*/
|
*/
|
||||||
interface Specification: Configurable{
|
interface Specification : Configurable {
|
||||||
operator fun get(name: String): MetaItem<Config>? = config[name]
|
operator fun get(name: String): MetaItem<Config>? = config[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,24 +26,29 @@ interface SpecificationBuilder<T : Specification> {
|
|||||||
fun wrap(meta: Meta): T = wrap(meta.toConfig())
|
fun wrap(meta: Meta): T = wrap(meta.toConfig())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : Specification> specification(wrapper: (Config) -> T): SpecificationBuilder<T> = object : SpecificationBuilder<T> {
|
fun <T : Specification> specification(wrapper: (Config) -> T): SpecificationBuilder<T> =
|
||||||
override fun wrap(config: Config): T = wrapper(config)
|
object : SpecificationBuilder<T> {
|
||||||
}
|
override fun wrap(config: Config): T = wrapper(config)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply specified configuration to configurable
|
* Apply specified configuration to configurable
|
||||||
*/
|
*/
|
||||||
fun <T : Configurable, C : Specification, S : SpecificationBuilder<C>> T.configure(spec: S, action: C.() -> Unit) = apply { spec.update(config, action) }
|
fun <T : Configurable, C : Specification, S : SpecificationBuilder<C>> T.configure(spec: S, action: C.() -> Unit) =
|
||||||
|
apply { spec.update(config, action) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update configuration using given specification
|
* Update configuration using given specification
|
||||||
*/
|
*/
|
||||||
fun <C : Specification, S : SpecificationBuilder<C>> Specification.update(spec: S, action: C.() -> Unit) = apply { spec.update(config, action) }
|
fun <C : Specification, S : SpecificationBuilder<C>> Specification.update(spec: S, action: C.() -> Unit) =
|
||||||
|
apply { spec.update(config, action) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a style based on given specification
|
* Create a style based on given specification
|
||||||
*/
|
*/
|
||||||
fun <C : Specification, S : SpecificationBuilder<C>> S.createStyle(action: C.() -> Unit): Meta = Config().also { update(it, action) }
|
fun <C : Specification, S : SpecificationBuilder<C>> S.createStyle(action: C.() -> Unit): Meta =
|
||||||
|
Config().also { update(it, action) }
|
||||||
|
|
||||||
|
|
||||||
fun <C : Specification> Specification.spec(spec: SpecificationBuilder<C>, key: String? = null) = ChildConfigDelegate<C>(key) { spec.wrap(config) }
|
fun <C : Specification> Specification.spec(spec: SpecificationBuilder<C>, key: String? = null) =
|
||||||
|
ChildConfigDelegate<C>(key) { spec.wrap(config) }
|
@ -44,7 +44,7 @@ class StyledConfig(val config: Config, style: Meta = EmptyMeta) : Config() {
|
|||||||
}
|
}
|
||||||
is MetaItem.ValueItem -> MetaItem.ValueItem(value.value)
|
is MetaItem.ValueItem -> MetaItem.ValueItem(value.value)
|
||||||
is MetaItem.NodeItem -> MetaItem.NodeItem(
|
is MetaItem.NodeItem -> MetaItem.NodeItem(
|
||||||
StyledConfig(value.node, styleValue?.node ?: EmptyMeta)
|
StyledConfig(value.node, styleValue?.node ?: EmptyMeta)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
key to item
|
key to item
|
||||||
|
@ -5,12 +5,12 @@ import kotlin.test.Test
|
|||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
|
||||||
class MetaBuilderTest{
|
class MetaBuilderTest {
|
||||||
@Test
|
@Test
|
||||||
fun testBuilder(){
|
fun testBuilder() {
|
||||||
val meta = buildMeta {
|
val meta = buildMeta {
|
||||||
"a" to 22
|
"a" to 22
|
||||||
"b" to listOf(1,2,3)
|
"b" to listOf(1, 2, 3)
|
||||||
this["c"] = "myValue".asValue()
|
this["c"] = "myValue".asValue()
|
||||||
"node" to {
|
"node" to {
|
||||||
"e" to 12.2
|
"e" to 12.2
|
||||||
|
@ -3,17 +3,17 @@ package hep.dataforge.names
|
|||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class NameTest{
|
class NameTest {
|
||||||
@Test
|
@Test
|
||||||
fun simpleName(){
|
fun simpleName() {
|
||||||
val name = "token1.token2.token3".toName()
|
val name = "token1.token2.token3".toName()
|
||||||
assertEquals("token2", name[1].toString())
|
assertEquals("token2", name[1].toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun equalityTest(){
|
fun equalityTest() {
|
||||||
val name1 = "token1.token2[2].token3".toName()
|
val name1 = "token1.token2[2].token3".toName()
|
||||||
val name2 = "token1".toName() + "token2[2].token3"
|
val name2 = "token1".toName() + "token2[2].token3"
|
||||||
assertEquals(name1,name2)
|
assertEquals(name1, name2)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,9 +9,9 @@ pluginManagement {
|
|||||||
|
|
||||||
rootProject.name = "dataforge-core"
|
rootProject.name = "dataforge-core"
|
||||||
include(
|
include(
|
||||||
":dataforge-meta",
|
":dataforge-meta",
|
||||||
":dataforge-meta-io",
|
":dataforge-meta-io",
|
||||||
":dataforge-context",
|
":dataforge-context",
|
||||||
":dataforge-data",
|
":dataforge-data",
|
||||||
":dataforge-io"
|
":dataforge-io"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user