Skip to content

Commit fe003d6

Browse files
authored
Merge pull request #899 from simple-robot/std-msg-reference
增加与消息引用相关的内容:标准消息元素类型 `MessageReference` 和 API `MessageContent.reference()`
2 parents 470ce89 + eb6b98f commit fe003d6

File tree

8 files changed

+157
-6
lines changed

8 files changed

+157
-6
lines changed

buildSrc/src/main/kotlin/P.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ sealed class P(override val group: String) : ProjectDetail() {
5252
5353
*/
5454
companion object {
55-
const val VERSION = "4.4.0"
56-
const val NEXT_VERSION = "4.4.0"
55+
const val VERSION = "4.5.0"
56+
const val NEXT_VERSION = "4.5.1"
5757
const val SNAPSHOT_VERSION = "$VERSION-SNAPSHOT"
5858
const val NEXT_SNAPSHOT_VERSION = "$NEXT_VERSION-SNAPSHOT"
5959

simbot-api/api/simbot-api.api

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,12 +1947,44 @@ public abstract interface class love/forte/simbot/message/MessageContent : love/
19471947
public abstract fun getId ()Llove/forte/simbot/common/id/ID;
19481948
public abstract fun getMessages ()Llove/forte/simbot/message/Messages;
19491949
public abstract fun getPlainText ()Ljava/lang/String;
1950+
public fun getReference ()Llove/forte/simbot/message/MessageReference;
1951+
public fun getReferenceAsync ()Ljava/util/concurrent/CompletableFuture;
1952+
public fun getReferenceReserve ()Llove/forte/simbot/suspendrunner/reserve/SuspendReserve;
1953+
public synthetic fun reference (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
1954+
public static synthetic fun reference$suspendImpl (Llove/forte/simbot/message/MessageContent;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
19501955
}
19511956

19521957
public final class love/forte/simbot/message/MessageContentKt {
19531958
public static final fun getSafePlainText (Llove/forte/simbot/message/MessageContent;)Ljava/lang/String;
19541959
}
19551960

1961+
public final class love/forte/simbot/message/MessageIdReference : love/forte/simbot/message/MessageReference {
1962+
public static final field Companion Llove/forte/simbot/message/MessageIdReference$Companion;
1963+
public fun <init> (Llove/forte/simbot/common/id/ID;)V
1964+
public final fun component1 ()Llove/forte/simbot/common/id/ID;
1965+
public final fun copy (Llove/forte/simbot/common/id/ID;)Llove/forte/simbot/message/MessageIdReference;
1966+
public static synthetic fun copy$default (Llove/forte/simbot/message/MessageIdReference;Llove/forte/simbot/common/id/ID;ILjava/lang/Object;)Llove/forte/simbot/message/MessageIdReference;
1967+
public fun equals (Ljava/lang/Object;)Z
1968+
public fun getId ()Llove/forte/simbot/common/id/ID;
1969+
public fun hashCode ()I
1970+
public fun toString ()Ljava/lang/String;
1971+
}
1972+
1973+
public synthetic class love/forte/simbot/message/MessageIdReference$$serializer : kotlinx/serialization/internal/GeneratedSerializer {
1974+
public static final field INSTANCE Llove/forte/simbot/message/MessageIdReference$$serializer;
1975+
public final fun childSerializers ()[Lkotlinx/serialization/KSerializer;
1976+
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
1977+
public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Llove/forte/simbot/message/MessageIdReference;
1978+
public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
1979+
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
1980+
public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Llove/forte/simbot/message/MessageIdReference;)V
1981+
public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer;
1982+
}
1983+
1984+
public final class love/forte/simbot/message/MessageIdReference$Companion {
1985+
public final fun serializer ()Lkotlinx/serialization/KSerializer;
1986+
}
1987+
19561988
public final class love/forte/simbot/message/MessageKt {
19571989
public static final fun messageElementPolymorphic (Lkotlinx/serialization/modules/SerializersModuleBuilder;Lkotlin/jvm/functions/Function1;)V
19581990
}
@@ -1972,6 +2004,10 @@ public final class love/forte/simbot/message/MessageReceipts {
19722004
public static final fun aggregation (Ljava/util/List;)Llove/forte/simbot/message/AggregatedMessageReceipt;
19732005
}
19742006

2007+
public abstract interface class love/forte/simbot/message/MessageReference : love/forte/simbot/message/StandardMessage {
2008+
public abstract fun getId ()Llove/forte/simbot/common/id/ID;
2009+
}
2010+
19752011
public abstract interface class love/forte/simbot/message/Messages : java/lang/Iterable, kotlin/jvm/internal/markers/KMappedMarker, love/forte/simbot/message/Message {
19762012
public static final field Companion Llove/forte/simbot/message/Messages$Companion;
19772013
public static fun builder ()Llove/forte/simbot/message/MessagesBuilder;

simbot-api/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ kotlin {
111111

112112
jvmTest {
113113
dependencies {
114+
implementation(libs.mockk)
115+
implementation(project(":simbot-logger-slf4j2-impl"))
114116
implementation(libs.kotlinx.coroutines.reactive)
115117
implementation(libs.kotlinx.coroutines.reactor)
116118
implementation(libs.kotlinx.coroutines.rx2)

simbot-api/src/commonMain/kotlin/love/forte/simbot/message/MessageContent.kt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import love.forte.simbot.ability.DeleteFailureException
2727
import love.forte.simbot.ability.DeleteOption
2828
import love.forte.simbot.ability.DeleteSupport
2929
import love.forte.simbot.common.id.ID
30+
import love.forte.simbot.suspendrunner.STP
3031
import kotlin.jvm.JvmSynthetic
3132

3233

@@ -50,7 +51,12 @@ public interface MessageContent : DeleteSupport {
5051

5152
/**
5253
* 消息本体中完整消息的消息链。
54+
* [messages] 中的所有元素都是可离线构造的,换言之都是直接通过事件本体解析而来的。
55+
* 如果存在某些例如必须进行网络查询才能得知的消息元素,则不会被包含在 [messages] 中。
5356
*
57+
* 如果想要获取消息引用信息,也可参考 [reference]。
58+
*
59+
* @see reference
5460
*/
5561
public val messages: Messages
5662

@@ -84,10 +90,35 @@ public interface MessageContent : DeleteSupport {
8490
*/
8591
@JvmSynthetic
8692
override suspend fun delete(vararg options: DeleteOption)
93+
94+
/**
95+
* 获取当前消息内容中有关 [消息引用][MessageReference] 的消息元素。
96+
*
97+
* [reference] 在明确不支持或直接通过 [messages] 寻找获取时,不会发生挂起。
98+
* 否则当需要通过网络查询结果时会产生挂起。
99+
*
100+
* [reference] 所得结果**不一定**是 [messages] 中的元素。
101+
* 如上所述,如果需要通过网络查询才能得到结果,则 [reference] 的结果不会包含在 [messages] 中。
102+
*
103+
* - 如果实现者尚未针对性地实现此API,则默认逻辑为:
104+
* 从 [messages] 中寻找第一个类型为 [MessageReference] 的元素。
105+
* - 如果实现者的所属平台不存在、不支持 _消息引用_ 的概念,则可能始终得到 `null`。
106+
* - 如果实现者的所属平台有明确的 _消息引用_ 概念,但是无法通过 [MessageReference] 这个类型进行表述,
107+
* 则使用 [reference] 时应当抛出信息明确的 [UnsupportedOperationException] 异常。
108+
*
109+
* @throws UnsupportedOperationException 如果实现者的所属平台有明确的 _消息引用_ 概念,
110+
* 但是无法通过 [MessageReference] 这个类型进行表述
111+
*
112+
* @since 4.5.0
113+
*/
114+
@STP
115+
public suspend fun reference(): MessageReference? =
116+
messages.firstOrNull { it is MessageReference } as? MessageReference?
117+
87118
}
88119

89120
/**
90-
* 如果 [MessageContent.plainText],则以空字符串 `""` 替代之。
121+
* 如果 [MessageContent.plainText] 为 `null`,则以空字符串 `""` 替代之。
91122
* @see MessageContent.plainText
92123
*/
93124
public inline val MessageContent.safePlainText: String get() = plainText ?: ""

simbot-api/src/commonMain/kotlin/love/forte/simbot/message/Messages.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ public sealed interface Messages : Message, Iterable<Message.Element> {
105105

106106
subclass(Emoji.serializer())
107107
subclass(Face.serializer())
108+
subclass(MessageIdReference.serializer())
109+
108110

109111
resolvePlatformStandardSerializers()
110112
}

simbot-api/src/commonMain/kotlin/love/forte/simbot/message/StandardMessages.kt

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import kotlin.jvm.*
5050
* - [RemoteImage]
5151
* - [表情消息][Face]
5252
* - [emoji][Emoji]
53+
* - [消息引用][MessageReference]
5354
*
5455
* JVM平台中部分扩展、辅助API通过静态类 `StandardMessages` 提供。
5556
*
@@ -382,8 +383,7 @@ public data class SimpleOfflineResourceImage(
382383
@Serializable(
383384
ResourceBase64Serializer::class
384385
) override val resource: Resource
385-
) :
386-
OfflineResourceImage
386+
) : OfflineResourceImage
387387

388388

389389
/**
@@ -480,3 +480,33 @@ public data class Emoji(public val id: ID) : StandardMessage, EmoticonMessage
480480
public data class Face(public val id: ID) : StandardMessage, EmoticonMessage
481481
//endregion
482482

483+
//region MessageReference
484+
485+
/**
486+
* 一个消息引用元素,用来表示对另一个消息元素的引用。
487+
* 可用于发送或接收,是否能应用取决于具体地实现。
488+
*
489+
* 当某个平台存在 _消息引用_ 的概念,但是无法使用 [MessageReference] 进行描述(例如它通过多重ID确定唯一身份,而不是唯一ID),
490+
* 则需要由平台实现者自行实现,无法使用 [MessageReference],也无法使用 [MessageContent.reference]。
491+
*
492+
* @since 4.5.0
493+
*
494+
* @see MessageContent.reference
495+
* @see MessageIdReference
496+
*/
497+
public interface MessageReference : StandardMessage {
498+
/**
499+
* 被引用的目标消息ID。
500+
*/
501+
public val id: ID
502+
503+
}
504+
505+
/**
506+
* 一个仅实现 [id] 的 [MessageReference] 简单实现。
507+
*/
508+
@Serializable
509+
@SerialName("m.std.messageReference.id")
510+
public data class MessageIdReference(override val id: ID) : MessageReference
511+
512+
//endregion
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2024. ForteScarlet.
3+
*
4+
* Project https://github.com/simple-robot/simpler-robot
5+
6+
*
7+
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
8+
*
9+
* This program is free software: you can redistribute it and/or modify
10+
* it under the terms of the GNU Lesser General Public License as published by
11+
* the Free Software Foundation, either version 3 of the License, or
12+
* (at your option) any later version.
13+
*
14+
* This program is distributed in the hope that it will be useful,
15+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
* Lesser GNU General Public License for more details.
18+
*
19+
* You should have received a copy of the Lesser GNU General Public License
20+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
*
22+
*/
23+
24+
package message
25+
26+
import io.mockk.coVerify
27+
import io.mockk.every
28+
import io.mockk.spyk
29+
import kotlinx.coroutines.runBlocking
30+
import love.forte.simbot.message.MessageContent
31+
import love.forte.simbot.message.emptyMessages
32+
import kotlin.test.Test
33+
34+
35+
/**
36+
*
37+
* @author ForteScarlet
38+
*/
39+
class MessageContentReferenceTests {
40+
41+
@Test
42+
fun contentReferenceTest() {
43+
val content = spyk<MessageContent>()
44+
every { content.messages } returns emptyMessages()
45+
46+
runBlocking { content.reference() }
47+
coVerify { content.messages }
48+
}
49+
50+
}

0 commit comments

Comments
 (0)