From bb9d2fb322ec80e7b6047d8c5b70eb2497980da2 Mon Sep 17 00:00:00 2001 From: Him188 Date: Mon, 23 Mar 2020 19:39:40 +0800 Subject: [PATCH] Make `SingleMessage` implement `CharSequence` and `Iterable` --- .../kotlin/net.mamoe.mirai/message/data/At.kt | 9 ++++--- .../net.mamoe.mirai/message/data/AtAll.kt | 15 ++++++++--- .../net.mamoe.mirai/message/data/Face.kt | 7 ++++- .../net.mamoe.mirai/message/data/Image.kt | 27 ++++++++++++++++--- .../net.mamoe.mirai/message/data/Message.kt | 25 ++++++++--------- .../net.mamoe.mirai/message/data/PlainText.kt | 6 ++++- .../message/data/QuoteReply.kt | 4 +-- .../net.mamoe.mirai/message/data/builder.kt | 9 +++++++ 8 files changed, 75 insertions(+), 27 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt index 35b402685..02fbb463a 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/At.kt @@ -29,7 +29,10 @@ import kotlin.jvm.JvmSynthetic * @see AtAll 全体成员 */ class At -private constructor(val target: Long, val display: String) : Message, MessageContent { +private constructor(val target: Long, val display: String) : + MessageContent, + CharSequence by display, + Comparable by display { /** * 构造一个 [At] 实例. 这是唯一的公开的构造方式. @@ -52,9 +55,9 @@ private constructor(val target: Long, val display: String) : Message, MessageCon override fun followedBy(tail: Message): CombinedMessage { if (tail is PlainText && tail.stringValue.startsWith(' ')) { - return super.followedBy(tail) + return super.followedBy(tail) } - return super.followedBy(PlainText(" ")) + tail + return super.followedBy(PlainText(" ")) + tail } } diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/AtAll.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/AtAll.kt index df748ddd5..1eb904247 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/AtAll.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/AtAll.kt @@ -15,6 +15,8 @@ package net.mamoe.mirai.message.data import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmName +private const val display = "@全体成员" + /** * "@全体成员". * @@ -22,15 +24,20 @@ import kotlin.jvm.JvmName * * @see At at 单个群成员 */ -object AtAll : Message, Message.Key, MessageContent { - override fun toString(): String = "@全体成员" +object AtAll : + Message.Key, + MessageContent, + CharSequence by display, + Comparable by display { + + override fun toString(): String = display // 自动为消息补充 " " override fun followedBy(tail: Message): CombinedMessage { if (tail is PlainText && tail.stringValue.startsWith(' ')) { - return super.followedBy(tail) + return super.followedBy(tail) } - return super.followedBy(PlainText(" ")) + tail + return super.followedBy(PlainText(" ")) + tail } } \ No newline at end of file diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Face.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Face.kt index c42e337e2..6de61b8fa 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Face.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Face.kt @@ -18,7 +18,12 @@ import kotlin.jvm.JvmName /** * QQ 自带表情 */ -class Face(val id: Int) : Message, MessageContent { +class Face private constructor(val id: Int, private val stringValue: String) : + MessageContent, + CharSequence by stringValue, Comparable by stringValue { + + constructor(id: Int) : this(id, "[mirai:face$id]") + override fun toString(): String = "[mirai:face$id]" /** diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Image.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Image.kt index 72baf8c40..994b396fc 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Image.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Image.kt @@ -44,6 +44,9 @@ interface Image : Message, MessageContent { } /** + * 通过 [Image.imageId] 构造一个 [Image] 以便发送. + * 这个图片必须是服务器已经存在的图片. + * * 请查看 `ExternalImageJvm` 获取更多创建 [Image] 的方法 */ @Suppress("FunctionName") @@ -57,9 +60,21 @@ fun Image(imageId: String): Image = when (imageId.length) { @MiraiInternalAPI("使用 Image") abstract class AbstractImage internal constructor() : Image { - final override fun toString(): String { - return "[mirai:$imageId]" - } + + private var _stringValue: String? = null + get() { + return field ?: kotlin.run { + field = "[mirai:$imageId]" + field + } + } + override val length: Int get() = _stringValue!!.length + override fun get(index: Int): Char = _stringValue!![index] + override fun subSequence(startIndex: Int, endIndex: Int): CharSequence = + _stringValue!!.subSequence(startIndex, endIndex) + + override fun compareTo(other: String): Int = _stringValue!!.compareTo(other) + final override fun toString(): String = _stringValue!! } // region 在线图片 @@ -120,7 +135,9 @@ suspend inline fun OfflineImage.queryOriginUrl(): String = queryUrl() /** - * 群图片 + * 群图片. + * + * [imageId] 形如 `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.png` (42 长度) */ // CustomFace @OptIn(MiraiInternalAPI::class) @@ -191,6 +208,8 @@ abstract class OnlineGroupImage : GroupImage(), OnlineImage /** * 好友图片 + * + * [imageId] 形如 `/f8f1ab55-bf8e-4236-b55e-955848d7069f` (37 长度) */ // NotOnlineImage @OptIn(MiraiInternalAPI::class) sealed class FriendImage : AbstractImage() { diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt index b05748dbd..c72d2b24f 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/Message.kt @@ -98,6 +98,14 @@ interface Message { return CombinedMessage(tail, this) } + /** + * 转换为易辨识的字符串. + * + * 各个 [SingleMessage] 的转换示例: + * [PlainText]: "Hello" + * [GroupImage]: "[mirai:{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.png]" + * [FriendImage]: "" + */ override fun toString(): String operator fun plus(another: Message): CombinedMessage = this.followedBy(another) @@ -121,24 +129,17 @@ fun Message.repeat(count: Int): MessageChain { inline operator fun Message.times(count: Int): MessageChain = this.repeat(count) -interface SingleMessage : Message +interface SingleMessage : Message, CharSequence, Comparable /** * 消息元数据, 即不含内容的元素. * 包括: [MessageSource] */ interface MessageMetadata : SingleMessage { - /* - fun iterator(): Iterator { - return object : Iterator { - var visited: Boolean = false - override fun hasNext(): Boolean = !visited - override fun next(): Message { - if (visited) throw NoSuchElementException() - return this@MessageMetadata.also { visited = true } - } - } - }*/ + override val length: Int get() = 0 + override fun get(index: Int): Char = ""[index] // produce uniform exception + override fun subSequence(startIndex: Int, endIndex: Int): CharSequence = "".subSequence(startIndex, endIndex) + override fun compareTo(other: String): Int = "".compareTo(other) } /** diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt index 95fe48a3e..950d05920 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/PlainText.kt @@ -23,7 +23,11 @@ import kotlin.jvm.JvmSynthetic * * 一般不需要主动构造 [PlainText], [Message] 可直接与 [String] 相加. Java 用户请使用 [MessageChain.plus] */ -inline class PlainText(val stringValue: String) : Message, MessageContent { +class PlainText(val stringValue: String) : + MessageContent, + Comparable by stringValue, + CharSequence by stringValue { + constructor(charSequence: CharSequence) : this(charSequence.toString()) override operator fun contains(sub: String): Boolean = sub in stringValue diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt index b23371bf6..ddc73e5dc 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/QuoteReply.kt @@ -29,10 +29,10 @@ import kotlin.jvm.JvmName * 总是使用 [quote] 来构造这个实例. */ open class QuoteReply -@MiraiInternalAPI constructor(val source: MessageSource) : Message, MessageContent { +@MiraiInternalAPI constructor(val source: MessageSource) : Message, MessageMetadata { companion object Key : Message.Key - override fun toString(): String = "" + final override fun toString(): String = "" } /** diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/builder.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/builder.kt index d61690477..6f24fca54 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/builder.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/data/builder.kt @@ -7,15 +7,22 @@ * https://github.com/mamoe/mirai/blob/master/LICENSE */ +@file:JvmMultifileClass +@file:JvmName("MessageUtils") + package net.mamoe.mirai.message.data +import kotlin.jvm.JvmMultifileClass +import kotlin.jvm.JvmName import kotlin.jvm.JvmOverloads +import kotlin.jvm.JvmSynthetic /** * 构建一个 [MessageChain] * * @see MessageChainBuilder */ +@JvmSynthetic inline fun buildMessageChain(block: MessageChainBuilder.() -> Unit): MessageChain { return MessageChainBuilder().apply(block).asMessageChain() } @@ -25,6 +32,7 @@ inline fun buildMessageChain(block: MessageChainBuilder.() -> Unit): MessageChai * * @see MessageChainBuilder */ +@JvmSynthetic inline fun buildMessageChain(initialSize: Int, block: MessageChainBuilder.() -> Unit): MessageChain { return MessageChainBuilder(initialSize).apply(block).asMessageChain() } @@ -34,6 +42,7 @@ inline fun buildMessageChain(initialSize: Int, block: MessageChainBuilder.() -> * * @see MessageChainBuilder */ +@JvmSynthetic inline fun buildMessageChain( container: MutableCollection, block: MessageChainBuilder.() -> Unit