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

e.ultra.mutator.0.77.0.source-code.MapMutator.kt Maven / Gradle / Ivy

package de.peekandpoke.ultra.mutator

fun  Map.mutator(

    onModify: OnModify>,
    backwardMapper: (M) -> T,
    forwardMapper: (T, OnModify) -> M

): MapMutator {

    return MapMutator(this, onModify, forwardMapper, backwardMapper)
}

@Suppress("Detekt.TooManyFunctions")
class MapMutator(

    original: Map,
    onModify: OnModify>,
    private val forwardMapper: (T, OnModify) -> M,
    private val backwardMapper: (M) -> T

) : MutatorBase, MutableMap>(original, onModify), Iterable> {

    operator fun plusAssign(value: Map) = plusAssign(value.entries.toList())

    operator fun plusAssign(value: List>) = plusAssign(
        value.associate { kv -> kv.key to backwardMapper(kv.value) }
    )

    override fun copy(input: Map) = input.toMutableMap()

    override fun iterator(): Iterator> = It(getResult(), forwardMapper)

    /**
     * Returns the size of the list
     */
    val size get() = getResult().size

    /**
     * Returns true when the list is empty
     */
    fun isEmpty() = getResult().isEmpty()

    /**
     * Clears the whole list
     */
    fun clear() = apply { getMutableResult().clear() }

    /**
     * Put multiple elements into the map
     */
    fun put(vararg pair: Pair) = apply { pair.forEach { (k, v) -> set(k, v) } }

    /**
     * Remove elements from the map by their keys
     */
    fun remove(vararg key: K) = apply {

        val contained = key.filter { getResult().containsKey(it) }

        if (contained.isNotEmpty()) {
            getMutableResult().apply {
                contained.forEach { k ->
                    remove(k)
                }
            }
        }
    }

    /**
     * Retains all elements in the list that match the filter
     */
    fun retainWhere(filter: (Map.Entry) -> Boolean) = apply { plusAssign(getResult().filter(filter).toMap()) }

    /**
     * Removes all elements from the the list that match the filter
     */
    fun removeWhere(filter: (Map.Entry) -> Boolean) = apply { retainWhere { !filter(it) } }

    /**
     * Get the element at the given index
     */
    operator fun get(index: K): M? = getResult()[index]?.let { entry -> forwardMapper(entry) { set(index, it) } }

    /**
     * Set the element at the given index
     */
    operator fun set(index: K, element: T) = apply {

        val current = getResult()[index]

        // We only trigger the cloning, when the value has changed
        if (current == null || current.isNotSameAs(element)) {
            getMutableResult()[index] = element
        }
    }

    /**
     * Map.Entry impl
     */
    internal data class Entry(override val key: KX, override val value: VX) : Map.Entry

    /**
     * Iterator impl
     */
    internal inner class It(map: Map, private val mapper: (T, OnModify) -> M) : Iterator> {

        private val inner = map.iterator()

        override fun hasNext() = inner.hasNext()

        override fun next(): Map.Entry {

            val next = inner.next()

            return Entry(next.key, mapper(next.value) { set(next.key, it) })
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy