mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-22 21:30:13 +08:00
Introduce NotNullMap and NotNullMutableMap
This commit is contained in:
parent
72df43db27
commit
8661627607
@ -1,15 +1,63 @@
|
|||||||
@file:Suppress("unused", "INAPPLICABLE_JVM_NAME")
|
@file:Suppress("unused", "INAPPLICABLE_JVM_NAME", "INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||||
|
|
||||||
package net.mamoe.mirai.console.data
|
package net.mamoe.mirai.console.data
|
||||||
|
|
||||||
import net.mamoe.mirai.console.data.PluginDataExtensions.withDefault
|
import net.mamoe.mirai.console.data.PluginDataExtensions.withDefault
|
||||||
import net.mamoe.mirai.console.internal.data.ShadowMap
|
import net.mamoe.mirai.console.internal.data.ShadowMap
|
||||||
|
import net.mamoe.mirai.console.util.ConsoleExperimentalAPI
|
||||||
|
import kotlin.internal.LowPriorityInOverloadResolution
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [PluginData] 相关一些扩展
|
* [PluginData] 相关一些扩展
|
||||||
*/
|
*/
|
||||||
public object PluginDataExtensions {
|
public object PluginDataExtensions {
|
||||||
|
|
||||||
|
@ConsoleExperimentalAPI
|
||||||
|
public open class NotNullMap<K, V> internal constructor(
|
||||||
|
private val delegate: Map<K, V>
|
||||||
|
) : Map<K, V> by delegate {
|
||||||
|
override fun get(key: K): V =
|
||||||
|
delegate[key] ?: error("Internal error: delegate[key] returned null for NotNullMap.get")
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"getOrDefault on NotNullMap always returns the value in the map, and defaultValue will never be returned.",
|
||||||
|
level = DeprecationLevel.WARNING,
|
||||||
|
replaceWith = ReplaceWith("this.get(key)")
|
||||||
|
)
|
||||||
|
override fun getOrDefault(key: K, defaultValue: V): V {
|
||||||
|
return super.getOrDefault(key, defaultValue)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") // as designed
|
||||||
|
public class NotNullMutableMap<K, V> internal constructor(
|
||||||
|
private val delegate: MutableMap<K, V>
|
||||||
|
) : MutableMap<K, V> by delegate, NotNullMap<K, V>(delegate) {
|
||||||
|
override fun get(key: K): V =
|
||||||
|
delegate[key] ?: error("Internal error: delegate[key] returned null for NotNullMutableMap.get")
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"getOrDefault on NotNullMutableMap always returns the value in the map, and defaultValue will never be returned.",
|
||||||
|
level = DeprecationLevel.WARNING,
|
||||||
|
replaceWith = ReplaceWith("this.get(key)")
|
||||||
|
)
|
||||||
|
override fun getOrDefault(key: K, defaultValue: V): V {
|
||||||
|
return super<MutableMap>.getOrDefault(key, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun put(key: K, value: V): V {
|
||||||
|
return delegate.put(key, value)
|
||||||
|
?: error("Internal error: delegate.put(key, value) returned null for NotNullMutableMap.put")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"putIfAbsent on NotNullMutableMap always does nothing.",
|
||||||
|
level = DeprecationLevel.WARNING,
|
||||||
|
replaceWith = ReplaceWith("")
|
||||||
|
)
|
||||||
|
override fun putIfAbsent(key: K, value: V): Nothing? = null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个代理对象, 当 [Map.get] 返回 `null` 时先放入一个 [LinkedHashMap], 再从 [this] 中取出链接自动保存的 [LinkedHashMap]. ([MutableMap.getOrPut] 的替代)
|
* 创建一个代理对象, 当 [Map.get] 返回 `null` 时先放入一个 [LinkedHashMap], 再从 [this] 中取出链接自动保存的 [LinkedHashMap]. ([MutableMap.getOrPut] 的替代)
|
||||||
*
|
*
|
||||||
@ -17,7 +65,7 @@ public object PluginDataExtensions {
|
|||||||
*/
|
*/
|
||||||
@JvmName("withEmptyDefaultMapImmutable")
|
@JvmName("withEmptyDefaultMapImmutable")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public fun <K, InnerE, InnerV> SerializerAwareValue<MutableMap<K, Map<InnerE, InnerV>>>.withEmptyDefault(): SerializerAwareValue<MutableMap<K, Map<InnerE, InnerV>>> {
|
public fun <K, InnerE, InnerV> SerializerAwareValue<MutableMap<K, Map<InnerE, InnerV>>>.withEmptyDefault(): SerializerAwareValue<NotNullMutableMap<K, Map<InnerE, InnerV>>> {
|
||||||
return this.withDefault { LinkedHashMap() }
|
return this.withDefault { LinkedHashMap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,7 +75,7 @@ public object PluginDataExtensions {
|
|||||||
*/
|
*/
|
||||||
@JvmName("withEmptyDefaultMap")
|
@JvmName("withEmptyDefaultMap")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public fun <K, InnerE, InnerV> SerializerAwareValue<MutableMap<K, MutableMap<InnerE, InnerV>>>.withEmptyDefault(): SerializerAwareValue<MutableMap<K, MutableMap<InnerE, InnerV>>> {
|
public fun <K, InnerE, InnerV> SerializerAwareValue<MutableMap<K, MutableMap<InnerE, InnerV>>>.withEmptyDefault(): SerializerAwareValue<NotNullMutableMap<K, MutableMap<InnerE, InnerV>>> {
|
||||||
return this.withDefault { LinkedHashMap() }
|
return this.withDefault { LinkedHashMap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +86,7 @@ public object PluginDataExtensions {
|
|||||||
*/
|
*/
|
||||||
@JvmName("withEmptyDefaultListImmutable")
|
@JvmName("withEmptyDefaultListImmutable")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public fun <K, E> SerializerAwareValue<MutableMap<K, List<E>>>.withEmptyDefault(): SerializerAwareValue<MutableMap<K, List<E>>> {
|
public fun <K, E> SerializerAwareValue<MutableMap<K, List<E>>>.withEmptyDefault(): SerializerAwareValue<NotNullMutableMap<K, List<E>>> {
|
||||||
return this.withDefault { ArrayList() }
|
return this.withDefault { ArrayList() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +96,7 @@ public object PluginDataExtensions {
|
|||||||
*/
|
*/
|
||||||
@JvmName("withEmptyDefaultList")
|
@JvmName("withEmptyDefaultList")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public fun <K, E> SerializerAwareValue<MutableMap<K, MutableList<E>>>.withEmptyDefault(): SerializerAwareValue<MutableMap<K, MutableList<E>>> {
|
public fun <K, E> SerializerAwareValue<MutableMap<K, MutableList<E>>>.withEmptyDefault(): SerializerAwareValue<NotNullMutableMap<K, MutableList<E>>> {
|
||||||
return this.withDefault { ArrayList() }
|
return this.withDefault { ArrayList() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +107,7 @@ public object PluginDataExtensions {
|
|||||||
*/
|
*/
|
||||||
@JvmName("withEmptyDefaultSetImmutable")
|
@JvmName("withEmptyDefaultSetImmutable")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public fun <K, E> SerializerAwareValue<MutableMap<K, Set<E>>>.withEmptyDefault(): SerializerAwareValue<MutableMap<K, Set<E>>> {
|
public fun <K, E> SerializerAwareValue<MutableMap<K, Set<E>>>.withEmptyDefault(): SerializerAwareValue<NotNullMutableMap<K, Set<E>>> {
|
||||||
return this.withDefault { LinkedHashSet() }
|
return this.withDefault { LinkedHashSet() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +117,7 @@ public object PluginDataExtensions {
|
|||||||
*/
|
*/
|
||||||
@JvmName("withEmptyDefaultSet")
|
@JvmName("withEmptyDefaultSet")
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
public fun <K, E> SerializerAwareValue<MutableMap<K, MutableSet<E>>>.withEmptyDefault(): SerializerAwareValue<MutableMap<K, MutableSet<E>>> {
|
public fun <K, E> SerializerAwareValue<MutableMap<K, MutableSet<E>>>.withEmptyDefault(): SerializerAwareValue<NotNullMutableMap<K, MutableSet<E>>> {
|
||||||
return this.withDefault { LinkedHashSet() }
|
return this.withDefault { LinkedHashSet() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,15 +126,47 @@ public object PluginDataExtensions {
|
|||||||
* 创建一个代理对象, 当 [Map.get] 返回 `null` 时先调用 [defaultValueComputer] 并放入 [Map], 再返回调用的返回值
|
* 创建一个代理对象, 当 [Map.get] 返回 `null` 时先调用 [defaultValueComputer] 并放入 [Map], 再返回调用的返回值
|
||||||
*/
|
*/
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@JvmName("withDefaultMapImmutableNotNull")
|
||||||
|
public fun <K, V : Any> SerializerAwareValue<Map<K, V>>.withDefault(defaultValueComputer: (K) -> V): SerializerAwareValue<NotNullMap<K, V>> {
|
||||||
|
@Suppress("UNCHECKED_CAST") // magic
|
||||||
|
return (this as SerializerAwareValue<MutableMap<K, V>>).withDefault(defaultValueComputer) as SerializerAwareValue<NotNullMap<K, V>>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个代理对象, 当 [Map.get] 返回 `null` 时先调用 [defaultValueComputer] 并放入 [Map], 再返回调用的返回值
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
@LowPriorityInOverloadResolution
|
||||||
@JvmName("withDefaultMapImmutable")
|
@JvmName("withDefaultMapImmutable")
|
||||||
public fun <K, V> SerializerAwareValue<Map<K, V>>.withDefault(defaultValueComputer: (K) -> V): SerializerAwareValue<Map<K, V>> {
|
public fun <K, V> SerializerAwareValue<Map<K, V>>.withDefault(defaultValueComputer: (K) -> V): SerializerAwareValue<Map<K, V>> {
|
||||||
@Suppress("UNCHECKED_CAST") // magic
|
@Suppress("UNCHECKED_CAST") // magic
|
||||||
return (this as SerializerAwareValue<MutableMap<K, V>>).withDefault(defaultValueComputer) as SerializerAwareValue<Map<K, V>>
|
return (this as SerializerAwareValue<MutableMap<K, V>>).withDefault(defaultValueComputer) as SerializerAwareValue<Map<K, V>>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@JvmName("withDefaultMapNotNull")
|
||||||
|
public fun <K, V : Any> SerializerAwareValue<MutableMap<K, V>>.withDefault(defaultValueComputer: (K) -> V): SerializerAwareValue<NotNullMutableMap<K, V>> {
|
||||||
|
val origin = this
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return SerializableValue(
|
||||||
|
object : CompositeMapValue<K, V> {
|
||||||
|
private val instance = NotNullMutableMap(createDelegateInstance(origin, defaultValueComputer))
|
||||||
|
|
||||||
|
override var value: Map<K, V>
|
||||||
|
get() = instance
|
||||||
|
set(value) {
|
||||||
|
origin.value = value as MutableMap<K, V> // erased cast
|
||||||
|
}
|
||||||
|
} as Value<NotNullMutableMap<K, V>>, // erased cast
|
||||||
|
this.serializer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建一个代理对象, 当 [Map.get] 返回 `null` 时先调用 [defaultValueComputer] 并放入 [Map], 再返回调用的返回值
|
* 创建一个代理对象, 当 [Map.get] 返回 `null` 时先调用 [defaultValueComputer] 并放入 [Map], 再返回调用的返回值
|
||||||
*/
|
*/
|
||||||
|
@LowPriorityInOverloadResolution
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@JvmName("withDefaultMap")
|
@JvmName("withDefaultMap")
|
||||||
public fun <K, V> SerializerAwareValue<MutableMap<K, V>>.withDefault(defaultValueComputer: (K) -> V): SerializerAwareValue<MutableMap<K, V>> {
|
public fun <K, V> SerializerAwareValue<MutableMap<K, V>>.withDefault(defaultValueComputer: (K) -> V): SerializerAwareValue<MutableMap<K, V>> {
|
||||||
@ -95,24 +175,7 @@ public object PluginDataExtensions {
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return SerializableValue(
|
return SerializableValue(
|
||||||
object : CompositeMapValue<K, V> {
|
object : CompositeMapValue<K, V> {
|
||||||
private val instance = object : MutableMap<K, V>, AbstractMap<K, V>() {
|
private val instance = createDelegateInstance(origin, defaultValueComputer)
|
||||||
override val entries: MutableSet<MutableMap.MutableEntry<K, V>> get() = origin.value.entries
|
|
||||||
override val keys: MutableSet<K> get() = origin.value.keys
|
|
||||||
override val values: MutableCollection<V> get() = origin.value.values
|
|
||||||
override fun clear() = origin.value.clear()
|
|
||||||
override fun putAll(from: Map<out K, V>) = origin.value.putAll(from)
|
|
||||||
override fun remove(key: K): V? = origin.value.remove(key)
|
|
||||||
override fun put(key: K, value: V): V? = origin.value.put(key, value)
|
|
||||||
|
|
||||||
override fun get(key: K): V? {
|
|
||||||
// the only difference
|
|
||||||
val result = origin.value[key]
|
|
||||||
if (result != null) return result
|
|
||||||
put(key, defaultValueComputer(key))
|
|
||||||
return origin.value[key]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override var value: Map<K, V>
|
override var value: Map<K, V>
|
||||||
get() = instance
|
get() = instance
|
||||||
set(value) {
|
set(value) {
|
||||||
@ -123,6 +186,57 @@ public object PluginDataExtensions {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <K, V> createDelegateInstance(
|
||||||
|
origin: SerializerAwareValue<MutableMap<K, V>>,
|
||||||
|
defaultValueComputer: (K) -> V
|
||||||
|
): MutableMap<K, V> {
|
||||||
|
return object : MutableMap<K, V>, AbstractMap<K, V>() {
|
||||||
|
override val entries: MutableSet<MutableMap.MutableEntry<K, V>> get() = origin.value.entries
|
||||||
|
override val keys: MutableSet<K> get() = origin.value.keys
|
||||||
|
override val values: MutableCollection<V> get() = origin.value.values
|
||||||
|
override fun clear() = origin.value.clear()
|
||||||
|
override fun putAll(from: Map<out K, V>) = origin.value.putAll(from)
|
||||||
|
override fun remove(key: K): V? = origin.value.remove(key)
|
||||||
|
override fun put(key: K, value: V): V? = origin.value.put(key, value)
|
||||||
|
|
||||||
|
override fun get(key: K): V? {
|
||||||
|
// the only difference
|
||||||
|
val result = origin.value[key]
|
||||||
|
if (result != null) return result
|
||||||
|
put(key, defaultValueComputer(key))
|
||||||
|
return origin.value[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换 [MutableMap] 的 key
|
||||||
|
*/
|
||||||
|
@JvmName("mapKeysNotNull")
|
||||||
|
@JvmStatic
|
||||||
|
public fun <OldK, NewK, V : Any> SerializerAwareValue<NotNullMutableMap<OldK, V>>.mapKeys(
|
||||||
|
oldToNew: (OldK) -> NewK,
|
||||||
|
newToOld: (NewK) -> OldK,
|
||||||
|
): SerializerAwareValue<NotNullMutableMap<NewK, V>> {
|
||||||
|
val origin = this
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return SerializableValue(
|
||||||
|
object : CompositeMapValue<NewK, V> {
|
||||||
|
private val instance =
|
||||||
|
NotNullMutableMap(ShadowMap({ origin.value }, oldToNew, newToOld, { it }, { it }))
|
||||||
|
|
||||||
|
override var value: Map<NewK, V>
|
||||||
|
get() = instance
|
||||||
|
set(value) {
|
||||||
|
origin.value =
|
||||||
|
value.mapKeysTo(NotNullMutableMap(LinkedHashMap())) { it.key.let(newToOld) } // erased cast
|
||||||
|
}
|
||||||
|
} as Value<NotNullMutableMap<NewK, V>>, // erased cast
|
||||||
|
this.serializer
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 替换 [MutableMap] 的 key
|
* 替换 [MutableMap] 的 key
|
||||||
@ -177,4 +291,72 @@ public object PluginDataExtensions {
|
|||||||
this.serializer
|
this.serializer
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换 [Map] 的 key
|
||||||
|
*/
|
||||||
|
@JvmName("mapKeysImmutableNotNull")
|
||||||
|
@JvmStatic
|
||||||
|
public fun <OldK, NewK, V : Any> SerializerAwareValue<NotNullMap<OldK, V>>.mapKeys(
|
||||||
|
oldToNew: (OldK) -> NewK,
|
||||||
|
newToOld: (NewK) -> OldK,
|
||||||
|
): SerializerAwareValue<NotNullMap<NewK, V>> {
|
||||||
|
val origin = this
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return SerializableValue(
|
||||||
|
object : CompositeMapValue<NewK, V> {
|
||||||
|
// casting Map to MutableMap is OK here, as we don't call mutable functions
|
||||||
|
private val instance =
|
||||||
|
NotNullMap(ShadowMap({ origin.value as MutableMap<OldK, V> }, oldToNew, newToOld, { it }, { it }))
|
||||||
|
|
||||||
|
override var value: Map<NewK, V>
|
||||||
|
get() = instance
|
||||||
|
set(value) {
|
||||||
|
origin.value =
|
||||||
|
value.mapKeysTo(NotNullMutableMap(LinkedHashMap())) { it.key.let(newToOld) } // erased cast
|
||||||
|
}
|
||||||
|
} as Value<NotNullMap<NewK, V>>, // erased cast
|
||||||
|
this.serializer
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,8 +44,10 @@ internal object ManagersConfig : AutoSavePluginConfig() {
|
|||||||
管理员列表
|
管理员列表
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
private val managers by value<MutableMap<Long, MutableSet<Long>>>().withEmptyDefault()
|
private val managers
|
||||||
.mapKeys(Bot::getInstance, Bot::id)
|
by value<MutableMap<Long, MutableSet<Long>>>()
|
||||||
|
.withEmptyDefault()
|
||||||
|
.mapKeys(Bot::getInstance, Bot::id)
|
||||||
|
|
||||||
internal operator fun get(bot: Bot): MutableSet<Long> = managers[bot]!!
|
internal operator fun get(bot: Bot): MutableSet<Long> = managers[bot]
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user