From 5188d8848324b772984da05b638239e5667e5ef3 Mon Sep 17 00:00:00 2001 From: Him188 Date: Sat, 4 Sep 2021 19:36:16 +0800 Subject: [PATCH] Improve `CheckableResponse` --- .../src/commonMain/kotlin/CheckableResult.kt | 50 ++++++++++++++++--- .../contact/announcement/AnnouncementsImpl.kt | 8 +-- .../network/protocol/data/proto/MsgSvc.kt | 7 +-- 3 files changed, 51 insertions(+), 14 deletions(-) diff --git a/mirai-core-utils/src/commonMain/kotlin/CheckableResult.kt b/mirai-core-utils/src/commonMain/kotlin/CheckableResult.kt index bc64340bc..91b637e56 100644 --- a/mirai-core-utils/src/commonMain/kotlin/CheckableResult.kt +++ b/mirai-core-utils/src/commonMain/kotlin/CheckableResult.kt @@ -28,6 +28,17 @@ public abstract class CheckableResponseA : CheckableResponse { final override val _errorMessage: String? get() = errorMessage } +@Serializable +public abstract class CheckableResponseB : CheckableResponse { + public abstract val result: Int + + @Suppress("SpellCheckingInspection") + public abstract val errmsg: String + + final override val _errorCode: Int get() = result + final override val _errorMessage: String get() = errmsg +} + public class DeserializationFailure( structType: KType, public val json: String, @@ -40,17 +51,42 @@ public class DeserializationFailure( } } -public fun T.checked(): T { +/* + * `check`: throws exception, or returns succeed value. + * `checked`: do `check` and wrap result into an `Either`. + */ + +public fun T.check(): T { check(_errorCode == 0) { "Error code: $_errorCode, Error message: $_errorMessage" } return this } -public fun DeserializationFailure.checked(): Nothing = throw this.createException() - -public inline fun Either.checked(): T { - return this.fold(onLeft = { it.checked() }, onRight = { it.checked() }) +public open class FailureResponse( + public val errorCode: Int, + public val errorMessage: String, +) { + public fun createException(): Exception { + return IllegalStateException("Error code: $errorCode, Error message: $errorMessage") + } } -public inline fun Either.checked(): T { - return this.fold(onLeft = { it.checked() }, onRight = { it }) +public inline fun T.checked(): Either { + if (_errorCode == 0) return Either(this) + return Either(FailureResponse(_errorCode, _errorMessage.toString())) +} + +public fun DeserializationFailure.check(): Nothing = throw this.createException() +public fun FailureResponse.check(): Nothing = throw this.createException() + +public inline fun Either.check(): T { + return this.fold(onLeft = { it.check() }, onRight = { it.check() }) +} + +public inline fun Either.check(): T { + return this.fold(onLeft = { it.check() }, onRight = { it }) +} + +@JvmName("checkedFailureResponseT") +public inline fun Either.check(): T { + return this.fold(onLeft = { it.check() }, onRight = { it }) } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/contact/announcement/AnnouncementsImpl.kt b/mirai-core/src/commonMain/kotlin/contact/announcement/AnnouncementsImpl.kt index 00d35d5c3..c25a6d1ba 100644 --- a/mirai-core/src/commonMain/kotlin/contact/announcement/AnnouncementsImpl.kt +++ b/mirai-core/src/commonMain/kotlin/contact/announcement/AnnouncementsImpl.kt @@ -188,8 +188,8 @@ internal object AnnouncementProtocol { cookie("p_uin", "o$id") cookie("skey", sKey) cookie("p_skey", psKey("qun.qq.com")) - }.loadSafelyAs(UploadImageResp.serializer()).checked() - return resp.id.replace(""", "\"").loadSafelyAs(GroupAnnouncementImage.serializer()).checked().toPublic() + }.loadSafelyAs(UploadImageResp.serializer()).check() + return resp.id.replace(""", "\"").loadSafelyAs(GroupAnnouncementImage.serializer()).check().toPublic() } @Serializable @@ -233,7 +233,7 @@ internal object AnnouncementProtocol { cookie("p_uin", "o$id") cookie("skey", sKey) cookie("p_skey", psKey("qun.qq.com")) - }.loadSafelyAs(SendGroupAnnouncementResp.serializer()).checked().fid + }.loadSafelyAs(SendGroupAnnouncementResp.serializer()).check().fid } suspend fun QQAndroidBot.getRawGroupAnnouncements( @@ -271,7 +271,7 @@ internal object AnnouncementProtocol { cookie("p_uin", "o$id") cookie("skey", sKey) cookie("p_skey", psKey("qun.qq.com")) - }.loadSafelyAs(DeleteResp.serializer()).checked() + }.loadSafelyAs(DeleteResp.serializer()).check() return true } diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/MsgSvc.kt b/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/MsgSvc.kt index 675051a00..628925acf 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/MsgSvc.kt +++ b/mirai-core/src/commonMain/kotlin/network/protocol/data/proto/MsgSvc.kt @@ -13,6 +13,7 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.protobuf.ProtoNumber import net.mamoe.mirai.internal.network.Packet import net.mamoe.mirai.internal.utils.io.ProtoBuf +import net.mamoe.mirai.utils.CheckableResponseB import net.mamoe.mirai.utils.EMPTY_BYTE_ARRAY @Serializable @@ -650,14 +651,14 @@ internal class MsgSvc : ProtoBuf { @Serializable internal class PbGetRoamMsgResp( - @ProtoNumber(1) @JvmField val result: Int = 0, - @ProtoNumber(2) @JvmField val errmsg: String = "", + @ProtoNumber(1) override val result: Int = 0, + @ProtoNumber(2) override val errmsg: String = "", @ProtoNumber(3) @JvmField val peerUin: Long = 0L, @ProtoNumber(4) @JvmField val lastMsgtime: Long = 0L, @ProtoNumber(5) @JvmField val random: Long = 0L, @ProtoNumber(6) @JvmField val msg: List = emptyList(), @ProtoNumber(7) @JvmField val sig: ByteArray = EMPTY_BYTE_ARRAY, - ) : ProtoBuf + ) : ProtoBuf, CheckableResponseB() @Serializable internal class PbDiscussReadedReportReq(