|
|
@@ -11,24 +11,30 @@
|
|
|
|
|
|
package net.mamoe.mirai.utils
|
|
|
|
|
|
+import kotlinx.serialization.Serializable
|
|
|
import java.util.concurrent.ConcurrentHashMap
|
|
|
import kotlin.contracts.InvocationKind
|
|
|
import kotlin.contracts.contract
|
|
|
|
|
|
+@Serializable
|
|
|
@JvmInline
|
|
|
-public value class TypeKey<out T>(public val name: String) {
|
|
|
+public value class TypeKey<T>(public val name: String) {
|
|
|
override fun toString(): String = "Key($name)"
|
|
|
|
|
|
- public inline infix fun <T> to(value: T): TypeSafeMap = buildTypeSafeMap { set(this@TypeKey, value) }
|
|
|
+ public inline infix fun to(value: T): TypeSafeMap = buildTypeSafeMap { set(this@TypeKey, value) }
|
|
|
}
|
|
|
|
|
|
-public interface TypeSafeMap {
|
|
|
+/**
|
|
|
+ * @see buildTypeSafeMap
|
|
|
+ */
|
|
|
+public sealed interface TypeSafeMap {
|
|
|
public val size: Int
|
|
|
|
|
|
public operator fun <T> get(key: TypeKey<T>): T
|
|
|
public operator fun <T> contains(key: TypeKey<T>): Boolean = get(key) != null
|
|
|
|
|
|
- public fun toMap(): Map<TypeKey<*>, Any?>
|
|
|
+ public fun toMapBoxed(): Map<TypeKey<*>, Any?>
|
|
|
+ public fun toMap(): Map<String, Any?>
|
|
|
|
|
|
public companion object {
|
|
|
public val EMPTY: TypeSafeMap = TypeSafeMapImpl(emptyMap())
|
|
|
@@ -46,15 +52,16 @@ public operator fun TypeSafeMap.plus(other: TypeSafeMap): TypeSafeMap {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-public interface MutableTypeSafeMap : TypeSafeMap {
|
|
|
+public sealed interface MutableTypeSafeMap : TypeSafeMap {
|
|
|
public operator fun <T> set(key: TypeKey<T>, value: T)
|
|
|
public fun <T> remove(key: TypeKey<T>): T?
|
|
|
public fun setAll(other: TypeSafeMap)
|
|
|
}
|
|
|
|
|
|
|
|
|
+@PublishedApi
|
|
|
internal open class TypeSafeMapImpl(
|
|
|
- internal open val map: Map<TypeKey<*>, Any?> = ConcurrentHashMap()
|
|
|
+ @PublishedApi internal open val map: Map<String, Any?> = ConcurrentHashMap()
|
|
|
) : TypeSafeMap {
|
|
|
override val size: Int get() = map.size
|
|
|
|
|
|
@@ -67,16 +74,17 @@ internal open class TypeSafeMapImpl(
|
|
|
}
|
|
|
|
|
|
override operator fun <T> get(key: TypeKey<T>): T =
|
|
|
- map[key]?.uncheckedCast() ?: throw NoSuchElementException(key.toString())
|
|
|
+ map[key.name]?.uncheckedCast() ?: throw NoSuchElementException(key.toString())
|
|
|
|
|
|
override operator fun <T> contains(key: TypeKey<T>): Boolean = get(key) != null
|
|
|
|
|
|
- override fun toMap(): Map<TypeKey<*>, Any?> = map
|
|
|
+ override fun toMapBoxed(): Map<TypeKey<*>, Any?> = map.mapKeys { TypeKey<Any?>(it.key) }
|
|
|
+ override fun toMap(): Map<String, Any?> = map
|
|
|
}
|
|
|
|
|
|
@PublishedApi
|
|
|
internal class MutableTypeSafeMapImpl(
|
|
|
- override val map: MutableMap<TypeKey<*>, Any?> = ConcurrentHashMap()
|
|
|
+ @PublishedApi override val map: MutableMap<String, Any?> = ConcurrentHashMap()
|
|
|
) : TypeSafeMap, MutableTypeSafeMap, TypeSafeMapImpl(map) {
|
|
|
override fun equals(other: Any?): Boolean {
|
|
|
return other is MutableTypeSafeMapImpl && other.map == this.map
|
|
|
@@ -87,7 +95,7 @@ internal class MutableTypeSafeMapImpl(
|
|
|
}
|
|
|
|
|
|
override operator fun <T> set(key: TypeKey<T>, value: T) {
|
|
|
- map[key] = value
|
|
|
+ map[key.name] = value
|
|
|
}
|
|
|
|
|
|
override fun setAll(other: TypeSafeMap) {
|
|
|
@@ -98,9 +106,13 @@ internal class MutableTypeSafeMapImpl(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- override fun <T> remove(key: TypeKey<T>): T? = map.remove(key)?.uncheckedCast()
|
|
|
+ override fun <T> remove(key: TypeKey<T>): T? = map.remove(key.name)?.uncheckedCast()
|
|
|
}
|
|
|
|
|
|
+public inline fun MutableTypeSafeMap(): MutableTypeSafeMap = MutableTypeSafeMapImpl()
|
|
|
+public inline fun MutableTypeSafeMap(map: Map<String, Any?>): MutableTypeSafeMap =
|
|
|
+ MutableTypeSafeMapImpl().also { it.map.putAll(map) }
|
|
|
+
|
|
|
public inline fun buildTypeSafeMap(block: MutableTypeSafeMap.() -> Unit): MutableTypeSafeMap {
|
|
|
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
|
|
return MutableTypeSafeMapImpl().apply(block)
|