
commonMain.dev.kord.cache.api.delegate.DelegatingDataCache.kt Maven / Gradle / Ivy
package dev.kord.cache.api.delegate
import dev.kord.cache.api.ConcurrentHashMap
import dev.kord.cache.api.DataCache
import dev.kord.cache.api.DataEntryCache
import dev.kord.cache.api.data.DataDescription
import kotlin.reflect.KType
import kotlin.reflect.typeOf
typealias Supplier = (cache: DataCache, description: DataDescription) -> DataEntryCache
typealias FullSupplier = (cache: DataCache, description: DataDescription) -> DataEntryCache
interface EntrySupplier {
suspend fun supply(cache: DataCache, description: DataDescription): DataEntryCache
companion object {
@Suppress("UNCHECKED_CAST")
operator fun invoke(supply: (cache: DataCache, description: DataDescription) -> DataEntryCache<*>) = object : EntrySupplier {
override suspend fun supply(cache: DataCache, description: DataDescription): DataEntryCache =
supply(cache, description as DataDescription) as DataEntryCache
}
}
}
/**
* A cache that delegates all operations to [DataEntryCaches][DataEntryCache], who are lazily loaded on [register].
*/
class DelegatingDataCache(private val supplier: EntrySupplier) : DataCache {
private val caches = ConcurrentHashMap>()
@Suppress("UNCHECKED_CAST")
override fun getEntry(type: KType): DataEntryCache? {
return caches[type] as? DataEntryCache
}
@Suppress("UNCHECKED_CAST")
override suspend fun register(description: DataDescription) {
caches[description.type] = supplier.supply(this, description as DataDescription)
}
companion object {
private class DelegateSupplier(private val default: Supplier, private val suppliers: MutableMap>) : EntrySupplier {
@Suppress("UNCHECKED_CAST")
override suspend fun supply(cache: DataCache, description: DataDescription): DataEntryCache {
val supplier = (suppliers[description.type] ?: default) as Supplier
return supplier(cache, description)
}
}
class Builder {
val suppliers: MutableMap> = mutableMapOf()
private var default: Supplier = { _, _ -> DataEntryCache.none() }
@Suppress("UNCHECKED_CAST")
inline fun forType(noinline supplier: Supplier) {
suppliers[typeOf()] = supplier as Supplier<*>
}
@Suppress("UNCHECKED_CAST")
fun forDescription(
description: DataDescription,
supplier: FullSupplier
) {
suppliers[description.type] = supplier as Supplier<*>
}
fun default(supplier: Supplier) {
default = supplier
}
fun build(): DataCache = DelegatingDataCache(DelegateSupplier(default, suppliers))
}
/**
* Creates a new [DataCache] configured by [builder].
* [Builder.default] will use a [DataEntryCache.none] to store entries.
*/
inline operator fun invoke(builder: Builder.() -> Unit = {}) = Builder().apply(builder).build()
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy