mirror of
https://github.com/hykilpikonna/AquaDX.git
synced 2026-05-20 12:18:15 -05:00
[M] Move core extensions to shared
This commit is contained in:
parent
adaa255dd3
commit
3dbb0095bf
5
.agents/rules/coding-guide.md
Normal file
5
.agents/rules/coding-guide.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
trigger: always_on
|
||||
---
|
||||
|
||||
Make sure `./gradlew build` compiles before you say you're done.
|
||||
|
|
@ -32,10 +32,7 @@ fun HttpServletResponse.details() = mapOf(
|
|||
|
||||
// HTTP
|
||||
operator fun HttpStatus.invoke(message: String? = null): Nothing = throw ApiException(value(), message ?: this.reasonPhrase)
|
||||
operator fun Int.minus(message: String): Nothing {
|
||||
ApiException.log.info("> Error $this: $message")
|
||||
throw ApiException(this, message)
|
||||
}
|
||||
|
||||
fun <R> parsing(block: () -> R) = try { block() }
|
||||
catch (e: ApiException) { throw e }
|
||||
catch (e: Exception) { 400 - e.message.toString() }
|
||||
|
|
|
|||
|
|
@ -1,29 +1,21 @@
|
|||
package icu.samnyan.aqua.net.utils
|
||||
|
||||
import ext.Str
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||
|
||||
|
||||
val SUCCESS = ResponseEntity.ok().body(mapOf("status" to "ok"))
|
||||
|
||||
class ApiException(val code: Int, message: Str) : RuntimeException(message) {
|
||||
companion object {
|
||||
val log = LoggerFactory.getLogger(ApiException::class.java)
|
||||
}
|
||||
|
||||
fun resp() = ResponseEntity.status(code).body(message.toString())
|
||||
}
|
||||
|
||||
fun Exception.simpleDescribe(): String = if (this is ApiException) "E${code}" else javaClass.simpleName
|
||||
|
||||
@ControllerAdvice(basePackages = ["icu.samnyan"])
|
||||
class GlobalExceptionHandler {
|
||||
@ExceptionHandler(ApiException::class)
|
||||
fun handleCustomApiException(e: ApiException): ResponseEntity<String> {
|
||||
// On error, return the error code and message
|
||||
return e.resp()
|
||||
}
|
||||
package icu.samnyan.aqua.net.utils
|
||||
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler
|
||||
|
||||
|
||||
val SUCCESS: ResponseEntity<Map<String, String>> = ResponseEntity.ok().body(mapOf("status" to "ok"))
|
||||
|
||||
fun ApiException.resp(): ResponseEntity<String> = ResponseEntity.status(code).body(message.toString())
|
||||
|
||||
fun Exception.simpleDescribe(): String = if (this is ApiException) "E${code}" else javaClass.simpleName
|
||||
|
||||
@ControllerAdvice(basePackages = ["icu.samnyan"])
|
||||
class GlobalExceptionHandler {
|
||||
@ExceptionHandler(ApiException::class)
|
||||
fun handleCustomApiException(e: ApiException): ResponseEntity<String> {
|
||||
// On error, return the error code and message
|
||||
return e.resp()
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ import io.ktor.client.request.*
|
|||
import io.ktor.client.statement.*
|
||||
import kotlin.random.Random
|
||||
import kotlin.random.nextInt
|
||||
import ext.ensureEndingSlash
|
||||
import ext.jsonMap
|
||||
|
||||
const val BOARD_ID = "ACAE-01A99999999"
|
||||
const val FULL_CLIENT_ID = "A123-45678909999"
|
||||
|
|
|
|||
|
|
@ -9,4 +9,11 @@ dependencies {
|
|||
api("jakarta.servlet:jakarta.servlet-api:6.0.0")
|
||||
api("com.fasterxml.jackson.core:jackson-annotations:2.17.0")
|
||||
api("com.fasterxml.jackson.core:jackson-databind:2.17.0")
|
||||
api("com.fasterxml.jackson.module:jackson-module-kotlin:2.17.0")
|
||||
|
||||
// Core libraries
|
||||
api("org.slf4j:slf4j-api:2.0.12")
|
||||
api("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
|
||||
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
|
||||
api("org.jetbrains.kotlin:kotlin-reflect:2.1.10")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
package ext
|
||||
|
||||
import icu.samnyan.aqua.net.utils.ApiException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.slf4j.LoggerFactory
|
||||
|
|
@ -37,12 +38,12 @@ val emailRegex = "^(?=.{1,64}@)[\\p{L}0-9_-]+(\\.[\\p{L}0-9_-]+)*@[^-][\\p{L}0-9
|
|||
fun Str.isValidEmail(): Bool = emailRegex.matches(this)
|
||||
|
||||
// Class resource
|
||||
object Ext { val log = logger() }
|
||||
object Ext
|
||||
fun res(name: Str) = Ext::class.java.getResourceAsStream(name)
|
||||
fun resStr(name: Str) = res(name)?.reader()?.readText()
|
||||
inline fun <reified T> resJson(name: Str, warn: Boolean = true) = resStr(name)?.let {
|
||||
JSON.decodeFromString<T>(it)
|
||||
} ?: run { if (warn) Ext.log.warn("Resource $name is not found"); null }
|
||||
} ?: run { if (warn) ApiException.log.warn("Resource $name is not found"); null }
|
||||
|
||||
// Encodings
|
||||
fun Long.toHex(len: Int = 16): Str = "0x${this.toString(len).padStart(len, '0').uppercase()}"
|
||||
|
|
@ -56,6 +57,10 @@ fun Any.long() = when (this) {
|
|||
is String -> toLong()
|
||||
else -> 400 - "Invalid number: $this"
|
||||
}
|
||||
operator fun Int.minus(message: String): Nothing {
|
||||
ApiException.log.info("> Error $this: $message")
|
||||
throw ApiException(this, message)
|
||||
}
|
||||
fun Any.uint32() = long() and 0xFFFFFFFF
|
||||
fun Any.int() = long().toInt()
|
||||
val Any.long get() = long()
|
||||
|
|
@ -120,17 +125,19 @@ val Str.some get() = ifBlank { null }
|
|||
val ByteArray.hexStr get() = toHexString()
|
||||
operator fun StringBuilder.plusAssign(other: String) { this.append(other) }
|
||||
|
||||
// Coroutine
|
||||
suspend fun <T> async(block: suspend kotlinx.coroutines.CoroutineScope.() -> T): T = withContext(Dispatchers.IO) { block() }
|
||||
// Coroutine-lite
|
||||
fun <T> thread(block: () -> T) = Thread { block() }.apply { start() }
|
||||
fun <T> Lock.maybeLock(block: () -> T) = if (tryLock()) try { block() } finally { unlock() } else null
|
||||
|
||||
// Coroutine
|
||||
suspend fun <T> async(block: suspend kotlinx.coroutines.CoroutineScope.() -> T): T = withContext(Dispatchers.IO) { block() }
|
||||
|
||||
// Paths
|
||||
fun path(part1: Str, vararg parts: Str) = Path.of(part1, *parts)
|
||||
fun Str.path() = Path.of(this)
|
||||
operator fun Path.div(part: Str) = resolve(part)
|
||||
operator fun File.div(fileName: Str) = File(this, fileName)
|
||||
fun Str.ensureEndingSlash() = if (endsWith('/')) this else "$this/"
|
||||
fun String.ensureEndingSlash() = if (endsWith('/')) this else "$this/"
|
||||
fun Str.ensureNoEndingSlash() = if (endsWith('/')) dropLast(1) else this
|
||||
|
||||
fun <T: Any> T.logger() = LoggerFactory.getLogger(this::class.java)
|
||||
|
|
@ -56,7 +56,7 @@ catch (e: Exception) {
|
|||
throw e
|
||||
}
|
||||
|
||||
fun String.jsonMap(): Map<String, Any?> = json() ?: emptyMap()
|
||||
fun String.jsonArray(): List<Map<String, Any?>> = json() ?: emptyList()
|
||||
fun String.jsonMaybeMap(): Map<String, Any?>? = json()
|
||||
fun String.jsonMaybeArray(): List<Map<String, Any?>>? = json()
|
||||
fun String.jsonMap(): Map<String, Any?> = json<Map<String, Any?>>() ?: emptyMap()
|
||||
fun String.jsonArray(): List<Map<String, Any?>> = json<List<Map<String, Any?>>>() ?: emptyList()
|
||||
fun String.jsonMaybeMap(): Map<String, Any?>? = json<Map<String, Any?>>()
|
||||
fun String.jsonMaybeArray(): List<Map<String, Any?>>? = json<List<Map<String, Any?>>>()
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package icu.samnyan.aqua.net.utils
|
||||
|
||||
import ext.Str
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
class ApiException(val code: Int, message: Str) : RuntimeException(message) {
|
||||
companion object {
|
||||
val log = LoggerFactory.getLogger(ApiException::class.java)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user