Make SingleMessage implement CharSequence and Iterable<String>

This commit is contained in:
Him188 2020-03-23 19:39:40 +08:00
parent 83064d0c37
commit bb9d2fb322
8 changed files with 75 additions and 27 deletions

View File

@ -29,7 +29,10 @@ import kotlin.jvm.JvmSynthetic
* @see AtAll 全体成员 * @see AtAll 全体成员
*/ */
class At 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<String> by display {
/** /**
* 构造一个 [At] 实例. 这是唯一的公开的构造方式. * 构造一个 [At] 实例. 这是唯一的公开的构造方式.
@ -52,9 +55,9 @@ private constructor(val target: Long, val display: String) : Message, MessageCon
override fun followedBy(tail: Message): CombinedMessage { override fun followedBy(tail: Message): CombinedMessage {
if (tail is PlainText && tail.stringValue.startsWith(' ')) { if (tail is PlainText && tail.stringValue.startsWith(' ')) {
return super<MessageContent>.followedBy(tail) return super.followedBy(tail)
} }
return super<MessageContent>.followedBy(PlainText(" ")) + tail return super.followedBy(PlainText(" ")) + tail
} }
} }

View File

@ -15,6 +15,8 @@ package net.mamoe.mirai.message.data
import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
private const val display = "@全体成员"
/** /**
* "@全体成员". * "@全体成员".
* *
@ -22,15 +24,20 @@ import kotlin.jvm.JvmName
* *
* @see At at 单个群成员 * @see At at 单个群成员
*/ */
object AtAll : Message, Message.Key<AtAll>, MessageContent { object AtAll :
override fun toString(): String = "@全体成员" Message.Key<AtAll>,
MessageContent,
CharSequence by display,
Comparable<String> by display {
override fun toString(): String = display
// 自动为消息补充 " " // 自动为消息补充 " "
override fun followedBy(tail: Message): CombinedMessage { override fun followedBy(tail: Message): CombinedMessage {
if (tail is PlainText && tail.stringValue.startsWith(' ')) { if (tail is PlainText && tail.stringValue.startsWith(' ')) {
return super<MessageContent>.followedBy(tail) return super.followedBy(tail)
} }
return super<MessageContent>.followedBy(PlainText(" ")) + tail return super.followedBy(PlainText(" ")) + tail
} }
} }

View File

@ -18,7 +18,12 @@ import kotlin.jvm.JvmName
/** /**
* QQ 自带表情 * QQ 自带表情
*/ */
class Face(val id: Int) : Message, MessageContent { class Face private constructor(val id: Int, private val stringValue: String) :
MessageContent,
CharSequence by stringValue, Comparable<String> by stringValue {
constructor(id: Int) : this(id, "[mirai:face$id]")
override fun toString(): String = "[mirai:face$id]" override fun toString(): String = "[mirai:face$id]"
/** /**

View File

@ -44,6 +44,9 @@ interface Image : Message, MessageContent {
} }
/** /**
* 通过 [Image.imageId] 构造一个 [Image] 以便发送.
* 这个图片必须是服务器已经存在的图片.
*
* 请查看 `ExternalImageJvm` 获取更多创建 [Image] 的方法 * 请查看 `ExternalImageJvm` 获取更多创建 [Image] 的方法
*/ */
@Suppress("FunctionName") @Suppress("FunctionName")
@ -57,9 +60,21 @@ fun Image(imageId: String): Image = when (imageId.length) {
@MiraiInternalAPI("使用 Image") @MiraiInternalAPI("使用 Image")
abstract class AbstractImage internal constructor() : 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 在线图片 // region 在线图片
@ -120,7 +135,9 @@ suspend inline fun OfflineImage.queryOriginUrl(): String = queryUrl()
/** /**
* 群图片 * 群图片.
*
* [imageId] 形如 `{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.png` (42 长度)
*/ */
// CustomFace // CustomFace
@OptIn(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
@ -191,6 +208,8 @@ abstract class OnlineGroupImage : GroupImage(), OnlineImage
/** /**
* 好友图片 * 好友图片
*
* [imageId] 形如 `/f8f1ab55-bf8e-4236-b55e-955848d7069f` (37 长度)
*/ // NotOnlineImage */ // NotOnlineImage
@OptIn(MiraiInternalAPI::class) @OptIn(MiraiInternalAPI::class)
sealed class FriendImage : AbstractImage() { sealed class FriendImage : AbstractImage() {

View File

@ -98,6 +98,14 @@ interface Message {
return CombinedMessage(tail, this) return CombinedMessage(tail, this)
} }
/**
* 转换为易辨识的字符串.
*
* 各个 [SingleMessage] 的转换示例:
* [PlainText]: "Hello"
* [GroupImage]: "[mirai:{01E9451B-70ED-EAE3-B37C-101F1EEBF5B5}.png]"
* [FriendImage]: ""
*/
override fun toString(): String override fun toString(): String
operator fun plus(another: Message): CombinedMessage = this.followedBy(another) 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) inline operator fun Message.times(count: Int): MessageChain = this.repeat(count)
interface SingleMessage : Message interface SingleMessage : Message, CharSequence, Comparable<String>
/** /**
* 消息元数据, 即不含内容的元素. * 消息元数据, 即不含内容的元素.
* 包括: [MessageSource] * 包括: [MessageSource]
*/ */
interface MessageMetadata : SingleMessage { interface MessageMetadata : SingleMessage {
/* override val length: Int get() = 0
fun iterator(): Iterator<Message> { override fun get(index: Int): Char = ""[index] // produce uniform exception
return object : Iterator<Message> { override fun subSequence(startIndex: Int, endIndex: Int): CharSequence = "".subSequence(startIndex, endIndex)
var visited: Boolean = false override fun compareTo(other: String): Int = "".compareTo(other)
override fun hasNext(): Boolean = !visited
override fun next(): Message {
if (visited) throw NoSuchElementException()
return this@MessageMetadata.also { visited = true }
}
}
}*/
} }
/** /**

View File

@ -23,7 +23,11 @@ import kotlin.jvm.JvmSynthetic
* *
* 一般不需要主动构造 [PlainText], [Message] 可直接与 [String] 相加. Java 用户请使用 [MessageChain.plus] * 一般不需要主动构造 [PlainText], [Message] 可直接与 [String] 相加. Java 用户请使用 [MessageChain.plus]
*/ */
inline class PlainText(val stringValue: String) : Message, MessageContent { class PlainText(val stringValue: String) :
MessageContent,
Comparable<String> by stringValue,
CharSequence by stringValue {
constructor(charSequence: CharSequence) : this(charSequence.toString()) constructor(charSequence: CharSequence) : this(charSequence.toString())
override operator fun contains(sub: String): Boolean = sub in stringValue override operator fun contains(sub: String): Boolean = sub in stringValue

View File

@ -29,10 +29,10 @@ import kotlin.jvm.JvmName
* 总是使用 [quote] 来构造这个实例. * 总是使用 [quote] 来构造这个实例.
*/ */
open class QuoteReply open class QuoteReply
@MiraiInternalAPI constructor(val source: MessageSource) : Message, MessageContent { @MiraiInternalAPI constructor(val source: MessageSource) : Message, MessageMetadata {
companion object Key : Message.Key<QuoteReply> companion object Key : Message.Key<QuoteReply>
override fun toString(): String = "" final override fun toString(): String = ""
} }
/** /**

View File

@ -7,15 +7,22 @@
* https://github.com/mamoe/mirai/blob/master/LICENSE * https://github.com/mamoe/mirai/blob/master/LICENSE
*/ */
@file:JvmMultifileClass
@file:JvmName("MessageUtils")
package net.mamoe.mirai.message.data package net.mamoe.mirai.message.data
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
import kotlin.jvm.JvmOverloads import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmSynthetic
/** /**
* 构建一个 [MessageChain] * 构建一个 [MessageChain]
* *
* @see MessageChainBuilder * @see MessageChainBuilder
*/ */
@JvmSynthetic
inline fun buildMessageChain(block: MessageChainBuilder.() -> Unit): MessageChain { inline fun buildMessageChain(block: MessageChainBuilder.() -> Unit): MessageChain {
return MessageChainBuilder().apply(block).asMessageChain() return MessageChainBuilder().apply(block).asMessageChain()
} }
@ -25,6 +32,7 @@ inline fun buildMessageChain(block: MessageChainBuilder.() -> Unit): MessageChai
* *
* @see MessageChainBuilder * @see MessageChainBuilder
*/ */
@JvmSynthetic
inline fun buildMessageChain(initialSize: Int, block: MessageChainBuilder.() -> Unit): MessageChain { inline fun buildMessageChain(initialSize: Int, block: MessageChainBuilder.() -> Unit): MessageChain {
return MessageChainBuilder(initialSize).apply(block).asMessageChain() return MessageChainBuilder(initialSize).apply(block).asMessageChain()
} }
@ -34,6 +42,7 @@ inline fun buildMessageChain(initialSize: Int, block: MessageChainBuilder.() ->
* *
* @see MessageChainBuilder * @see MessageChainBuilder
*/ */
@JvmSynthetic
inline fun buildMessageChain( inline fun buildMessageChain(
container: MutableCollection<Message>, container: MutableCollection<Message>,
block: MessageChainBuilder.() -> Unit block: MessageChainBuilder.() -> Unit