You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Maps.kt 2.0KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. package com.dmdirc.ktirc.model
  2. import com.dmdirc.ktirc.io.CaseMapping
  3. import java.util.*
  4. /**
  5. * Provides a case-insensitive mapping from a String to some value, according to the provided [CaseMapping].
  6. */
  7. abstract class CaseInsensitiveMap<T>(private val caseMappingProvider: () -> CaseMapping, private val nameOf: (T) -> String) : Iterable<T> {
  8. private val values = Collections.synchronizedSet(HashSet<T>())
  9. /** Gets the value of the given key, if present. */
  10. operator fun get(name: String) = synchronized(values) { values.find { caseMappingProvider().areEquivalent(nameOf(it), name) } }
  11. internal operator fun plusAssign(value: T): Unit = synchronized(values) {
  12. require(get(nameOf(value)) == null) { "Value already registered: ${nameOf(value)}" }
  13. values.add(value)
  14. }
  15. internal operator fun minusAssign(name: String): Unit = synchronized(values) {
  16. values.removeIf { caseMappingProvider().areEquivalent(nameOf(it), name) }
  17. }
  18. /** Returns true if the given key exists in this map. */
  19. operator fun contains(name: String) = get(name) != null
  20. /** Provides a read-only iterator over the values in this map. */
  21. override fun iterator() = HashSet(values).iterator().iterator()
  22. internal fun clear() = values.clear()
  23. internal fun removeIf(predicate: (T) -> Boolean): Unit = synchronized(values) {
  24. values.removeIf(predicate)
  25. }
  26. }
  27. /** Maps a channel name to a [ChannelState] instance. */
  28. class ChannelStateMap(caseMappingProvider: () -> CaseMapping) : CaseInsensitiveMap<ChannelState>(caseMappingProvider, ChannelState::name)
  29. /** Maps a nickname to a [ChannelUser] instance. */
  30. class ChannelUserMap(caseMappingProvider: () -> CaseMapping) : CaseInsensitiveMap<ChannelUser>(caseMappingProvider, ChannelUser::nickname)
  31. /** Maps a nickname to a [KnownUser] instance. */
  32. class UserMap(caseMappingProvider: () -> CaseMapping) : CaseInsensitiveMap<KnownUser>(caseMappingProvider, { it.details.nickname })