
jvmMain.space.kscience.dataforge.data.select.kt Maven / Gradle / Ivy
package space.kscience.dataforge.data
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.matches
import kotlin.reflect.KType
import kotlin.reflect.full.isSubtypeOf
import kotlin.reflect.typeOf
/**
* Cast the node to given type if the cast is possible or return null
*/
@Suppress("UNCHECKED_CAST")
private fun Data<*>.castOrNull(type: KType): Data? =
if (!this.type.isSubtypeOf(type)) null else object : Data by (this as Data) {
override val type: KType = type
}
/**
* Select all data matching given type and filters. Does not modify paths
*/
@OptIn(DFExperimental::class)
@PublishedApi
internal fun DataSet<*>.select(
type: KType,
namePattern: Name? = null,
): ActiveDataSet = object : ActiveDataSet {
override val dataType = type
override fun flow(): Flow> = [email protected]().filter { datum ->
datum.type.isSubtypeOf(type) && (namePattern == null || datum.name.matches(namePattern))
}.map {
@Suppress("UNCHECKED_CAST")
it as NamedData
}
override suspend fun getData(name: Name): Data? = [email protected](name)?.castOrNull(type)
override val updates: Flow = [email protected] {
val datum = [email protected](it)
datum?.type?.isSubtypeOf(type) ?: false
}
}
/**
* Select a single datum of the appropriate type
*/
public inline fun DataSet<*>.select(namePattern: Name? = null): DataSet =
select(typeOf(), namePattern)
public suspend fun DataSet<*>.selectOne(type: KType, name: Name): NamedData? =
getData(name)?.castOrNull(type)?.named(name)
public suspend inline fun DataSet<*>.selectOne(name: Name): NamedData? = selectOne(typeOf(), name)
public suspend inline fun DataSet<*>.selectOne(name: String): NamedData? =
selectOne(typeOf(), Name.parse(name))
© 2015 - 2025 Weber Informatics LLC | Privacy Policy