com.lightningkite.lightningdb.Modification.ext.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of server-core Show documentation
Show all versions of server-core Show documentation
A set of tools to fill in/replace what Ktor is lacking in.
The newest version!
package com.lightningkite.lightningdb
import kotlin.reflect.KProperty1
fun Modification.forFieldOrNull(field: KProperty1): Modification? {
return when (this) {
is Modification.Chain -> modifications.mapNotNull { it.forFieldOrNull(field) }.takeUnless { it.isEmpty() }
?.let { Modification.Chain(it) }
is Modification.OnField<*, *> -> if (this.key == field) this.modification as Modification else null
else -> null
}
}
fun Modification.vet(field: KProperty1, onModification: (Modification) -> Unit) {
when (this) {
is Modification.Assign -> onModification(Modification.Assign(field.get(this.value)))
is Modification.Chain -> modifications.forEach { it.vet(field, onModification) }
is Modification.OnField<*, *> -> if (this.key == field) (this.modification as Modification).vet(
onModification
) else null
else -> {}
}
}
fun Modification.vet(onModification: (Modification) -> Unit) {
when (this) {
is Modification.Chain -> modifications.forEach { it.vet(onModification) }
else -> onModification(this)
}
}
@Suppress("UNCHECKED_CAST")
fun Modification<*>.vet(fieldChain: List>, onModification: (Modification) -> Unit) {
val field: KProperty1<*, *> = fieldChain.firstOrNull() ?: run {
onModification(this as Modification)
return
}
when (this) {
is Modification.Assign -> {
var value = this.value
for (key in fieldChain) {
value = (key as KProperty1).get(value)
}
onModification(Modification.Assign(value as V))
}
is Modification.Chain -> modifications.forEach { it.vet(fieldChain, onModification) }
is Modification.OnField<*, *> -> if (this.key == field) this.modification.vet(
fieldChain.drop(1),
onModification
)
is Modification.IfNotNull -> this.modification.vet(fieldChain, onModification)
else -> {}
}
}
fun Modification.map(
field: KProperty1,
onModification: (Modification) -> Modification,
): Modification {
return when (this) {
is Modification.Chain -> modifications.map { it.map(field, onModification) }.let { Modification.Chain(it) }
is Modification.OnField<*, *> -> if (this.key == field) (this as Modification.OnField).copy(
modification = onModification(
modification
)
) else this as Modification
is Modification.Assign -> Modification.Assign(
field.setCopy(
this.value,
onModification(Modification.Assign(field.get(this.value))).let { it as Modification.Assign }.value
)
)
else -> this
}
}
suspend fun Modification.mapSuspend(
field: KProperty1,
onModification: suspend (Modification) -> Modification,
): Modification {
return when (this) {
is Modification.Chain -> modifications.map { it.mapSuspend(field, onModification) }.let { Modification.Chain(it) }
is Modification.OnField<*, *> -> if (this.key == field) (this as Modification.OnField).copy(
modification = onModification(
modification
)
) else this as Modification
is Modification.Assign -> Modification.Assign(
field.setCopy(
this.value,
onModification(Modification.Assign(field.get(this.value))).let { it as Modification.Assign }.value
)
)
else -> this
}
}