All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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