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