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

commonMain.aws.smithy.kotlin.runtime.util.Attributes.kt Maven / Gradle / Ivy

/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

package aws.smithy.kotlin.runtime.util

/**
 * Specifies a key for an attribute
 *
 * @param T is the type of the vale stored in the attribute
 * @param name the name of the attribute (for diagnostics)
 */
class AttributeKey(val name: String) {
    override fun toString(): String = if (name.isBlank()) super.toString() else "ExecutionAttributeKey: $name"
}

/**
 * Generic type safe property bag
 */
interface Attributes {
    /**
     * Get a value of the attribute for the specified [key] or null
     */
    fun  getOrNull(key: AttributeKey): T?

    /**
     * Check if an attribute with the specified [key] exists
     */
    operator fun contains(key: AttributeKey<*>): Boolean

    /**
     * Creates or changes an attribute with the specified [key] using [value]
     */
    operator fun  set(key: AttributeKey, value: T)

    /**
     * Removes an attribute with the specified [key]
     */
    fun  remove(key: AttributeKey)

    /**
     * Gets a value of the attribute for the specified [key], or calls supplied [block] to compute its value
     */
    fun  computeIfAbsent(key: AttributeKey, block: () -> T): T

    /**
     * Get a set of all the keys
     */
    val keys: Set>

    companion object {
        /**
         * Create an attributes instance
         */
        operator fun invoke(): Attributes = AttributesImpl()
    }
}

/**
 * Gets a value of the attribute for the specified [key] or throws an [IllegalStateException] if key does not exist
 */
operator fun  Attributes.get(key: AttributeKey): T = getOrNull(key) ?: throw IllegalStateException("No instance for $key")

/**
 * Removes an attribute with the specified [key] and returns its current value, throws an exception if an attribute doesn't exist
 */
fun  Attributes.take(key: AttributeKey): T = get(key).also { remove(key) }

/**
 * Set a value for [key] only if it is not already set
 */
fun  Attributes.putIfAbsent(key: AttributeKey, value: T) {
    if (!contains(key)) set(key, value)
}

/**
 * Set a value for [key] only if [value] is not null
 */
fun  Attributes.setIfValueNotNull(key: AttributeKey, value: T?) {
    if (value != null) set(key, value)
}

/**
 * Removes an attribute with the specified [key] and returns its current value, returns `null` if an attribute doesn't exist
 */
fun  Attributes.takeOrNull(key: AttributeKey): T? = getOrNull(key).also { remove(key) }

/**
 * Merge another attributes instance into this set of attributes favoring [other]
 */
fun Attributes.merge(other: Attributes) {
    other.keys.forEach {
        @Suppress("UNCHECKED_CAST")
        set(it as AttributeKey, other[it])
    }
}

private class AttributesImpl : Attributes {
    private val map: MutableMap, Any> = mutableMapOf()

    @Suppress("UNCHECKED_CAST")
    override fun  getOrNull(key: AttributeKey): T? = map[key] as T?

    override fun contains(key: AttributeKey<*>): Boolean = map.contains(key)

    override fun  set(key: AttributeKey, value: T) {
        map[key] = value
    }

    override fun  remove(key: AttributeKey) {
        map.remove(key)
    }

    override fun  computeIfAbsent(key: AttributeKey, block: () -> T): T {
        val value = getOrNull(key)
        if (value != null) return value

        val result = block()
        map[key] = result
        return result
    }

    override val keys: Set>
        get() = map.keys
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy