Skip to content

Instantly share code, notes, and snippets.

@47star
Created May 15, 2023 04:20
Show Gist options
  • Save 47star/0bf09dcf91df482271dffc506fd70336 to your computer and use it in GitHub Desktop.
Save 47star/0bf09dcf91df482271dffc506fd70336 to your computer and use it in GitHub Desktop.
Attribute Container for Kotlin Coroutines
import kotlinx.coroutines.currentCoroutineContext
import kotlin.coroutines.CoroutineContext
interface AttributeContainer : CoroutineContext.Element {
@InternalApi
data class Key(val fqName: String) : CoroutineContext.Key<AttributeContainer>
@InternalApi
override val key: CoroutineContext.Key<*> get() = Key(fqName)
val fqName: String get() = this::class.toString()
}
suspend inline fun <reified T : AttributeContainer> container(): T? =
@OptIn(InternalApi::class)
currentCoroutineContext()[AttributeContainer.Key(T::class.toString())] as? T
suspend inline fun <reified T : AttributeContainer> run(block: T.() -> Unit) {
container<T>()?.block()
}
@RequiresOptIn
private annotation class InternalApi
data class MyContext(
val userName: String,
) : AttributeContainer
suspend fun main() {
withContext(MyContext(userName = "DongHoon")) {
println(container<MyContext>()?.userName) // DongHoon
a()
}
}
suspend fun a() = run<MyContext> {
println(userName) // DongHoon
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment