Actuals.kt 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. /*
  2. * Copyright 2019-2021 Mamoe Technologies and contributors.
  3. *
  4. * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  5. * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
  6. *
  7. * https://github.com/mamoe/mirai/blob/master/LICENSE
  8. */
  9. @file:JvmMultifileClass
  10. @file:Suppress("NOTHING_TO_INLINE")
  11. package net.mamoe.mirai.utils
  12. import java.util.*
  13. import kotlin.reflect.KClass
  14. import kotlin.reflect.full.createInstance
  15. public actual fun ByteArray.encodeBase64(): String {
  16. return Base64.getEncoder().encodeToString(this)
  17. }
  18. public actual fun String.decodeBase64(): ByteArray {
  19. return Base64.getDecoder().decode(this)
  20. }
  21. public actual inline fun <reified E> Throwable.unwrap(): Throwable {
  22. if (this !is E) return this
  23. return this.findCause { it !is E }
  24. ?.also { it.addSuppressed(this) }
  25. ?: this
  26. }
  27. public actual fun <T : Any> loadService(clazz: KClass<out T>, fallbackImplementation: String?): T {
  28. var suppressed: Throwable? = null
  29. return ServiceLoader.load(clazz.java).firstOrNull()
  30. ?: runCatching { findCreateInstance<T>(fallbackImplementation) }.onFailure { suppressed = it }.getOrNull()
  31. ?: throw NoSuchElementException("Could not find an implementation for service class ${clazz.qualifiedName}").apply {
  32. if (suppressed != null) addSuppressed(suppressed)
  33. }
  34. }
  35. private fun <T : Any> findCreateInstance(fallbackImplementation: String?): T {
  36. return Class.forName(fallbackImplementation).cast<Class<out T>>().kotlin.run { objectInstance ?: createInstance() }
  37. }
  38. public actual fun <T : Any> loadServiceOrNull(clazz: KClass<out T>, fallbackImplementation: String?): T? {
  39. return ServiceLoader.load(clazz.java).firstOrNull()
  40. ?: runCatching { findCreateInstance<T>(fallbackImplementation) }.getOrNull()
  41. }