Skip to content

Commit

Permalink
Merge pull request #821 from simple-robot/resource-image-resolver
Browse files Browse the repository at this point in the history
StringResource 拆分为 StringReadableResource;增加 Resource 和 OfflineImage 的 Resolver 来允许组件等第三方更快速的分流它们的可能内容物
  • Loading branch information
ForteScarlet committed Apr 13, 2024
2 parents fe0a197 + 17f1533 commit 402f8af
Show file tree
Hide file tree
Showing 11 changed files with 1,088 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
* Copyright (c) 2024. ForteScarlet.
*
* Project https://github.com/simple-robot/simpler-robot
* Email ForteScarlet@163.com
*
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Lesser GNU General Public License for more details.
*
* You should have received a copy of the Lesser GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

package love.forte.simbot.message

import love.forte.simbot.resource.ByteArrayResource
import love.forte.simbot.resource.Resource
import love.forte.simbot.resource.ResourceResolver
import love.forte.simbot.resource.ResourceResolver.Companion.resolve
import love.forte.simbot.resource.StringResource
import kotlin.jvm.JvmStatic


/**
* 使用 [OfflineImageResolver] 分析处理一个 [OfflineImage].
* 类似于 `visitor` 的用法,与常见地访问器区别于通常情况下只会有一个 `resolve*`
* 会最终执行。
*
* 在 JVM 平台会提供一个具有更多能力的类型。
*
* @author ForteScarlet
*/
public interface OfflineImageResolver<C> {

/**
* 处理一个类型为未知的 [OfflineImage] 的 image.
*/
public fun resolveUnknown(image: OfflineImage, context: C)

/**
* 处理一个类型为 [OfflineByteArrayImage] 的 image.
*/
public fun resolveByteArray(image: OfflineByteArrayImage, context: C)

/**
* 处理一个类型为 [OfflineResourceImage] 的 image.
*/
public fun resolveResource(image: OfflineResourceImage, context: C)

public companion object {
/**
* 使用 [this] 分析处理 [image].
*/
@JvmStatic
public fun <C> OfflineImageResolver<C>.resolve(image: OfflineImage, context: C) {
when (image) {
is OfflineByteArrayImage -> resolveByteArray(image, context)
is OfflineResourceImage -> resolveResource(image, context)
else -> resolveUnknown(image, context)
}
}
}
}

/**
* 继承 [OfflineImageResolver] 和 [ResourceResolver],
* 对其中可能出现的实际内容物(例如 [ByteArray] 或 [String])进行处理。
*/
public interface OfflineImageValueResolver<C> :
OfflineImageResolver<C>,
ResourceResolver<C> {
/**
* 处理可能来自 [OfflineImage] 或 [Resource] 中的 [ByteArray]。
*/
public fun resolveByteArray(byteArray: ByteArray, context: C)

/**
* 处理可能来自 [OfflineImage] 或 [Resource] 中的 [String]。
*/
public fun resolveString(string: String, context: C)

/**
* 使用 [resolveByteArray] 处理 [OfflineByteArrayImage.data].
*/
override fun resolveByteArray(image: OfflineByteArrayImage, context: C) {
resolveByteArray(image.data(), context)
}

/**
* 使用 [resolveByteArray] 处理 [ByteArrayResource.data].
*/
override fun resolveByteArray(resource: ByteArrayResource, context: C) {
resolveByteArray(resource.data(), context)
}

/**
* 使用 [StringResource] 处理 [StringResource.string].
*/
override fun resolveString(resource: StringResource, context: C) {
resolveString(resource.string(), context)
}

override fun resolveResource(image: OfflineResourceImage, context: C) {
resolve(image.resource, context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Project https://github.com/simple-robot/simpler-robot
* Email ForteScarlet@163.com
*
* This file is part of the Simple Robot Library.
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand Down Expand Up @@ -132,16 +132,27 @@ private data class ByteArrayResourceImpl(private val raw: ByteArray) : ByteArray
}

/**
* 可以读取到 [String] 格式内容的 [Resource]。
* 一个可以读取到 [String] 内容物的拓展类型。
* 是其他 [Resource] 类型的附加能力,但不属于一个标准的 [Resource] 类型。
*/
public interface StringResource : Resource {
public interface StringReadableResource : Resource {
/**
* 读取此资源的 [String] 内容。
*/
@Throws(Exception::class)
public fun string(): String
}

/**
* 直接使用 [String] 作为内容的 [Resource]。
*/
public interface StringResource : StringReadableResource {
/**
* 读取此资源的 [String] 内容。
*/
override fun string(): String
}

/**
* 通过提供的 [String] 直接构建一个 [StringResource]。
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2024. ForteScarlet.
*
* Project https://github.com/simple-robot/simpler-robot
* Email ForteScarlet@163.com
*
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Lesser GNU General Public License for more details.
*
* You should have received a copy of the Lesser GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

package love.forte.simbot.resource

import kotlin.jvm.JvmStatic


/**
* 使用 [ResourceResolver] 分析处理一个 [Resource].
* 类似于 `visitor` 的用法,与常见地访问器区别于通常情况下只会有一个 `resolve*`
* 会最终执行。
*
* 在 JVM 平台会提供一个具有更多能力的类型。
*
* @author ForteScarlet
*/
public interface ResourceResolver<C> {
/**
* 处理一个未知的 [Resource] 类型的 resource.
*/
public fun resolveUnknown(resource: Resource, context: C)

/**
* 处理一个 [ByteArrayResource] 类型的 resource.
*/
public fun resolveByteArray(resource: ByteArrayResource, context: C)

/**
* 处理一个 [StringResource] 类型的 resource.
*/
public fun resolveString(resource: StringResource, context: C)

public companion object {
/**
* 使用 [this] 解析 [resource].
*/
@JvmStatic
public fun <C> ResourceResolver<C>.resolve(resource: Resource, context: C) {
when (resource) {
is ByteArrayResource -> resolveByteArray(resource, context)
is StringResource -> resolveString(resource, context)
else -> resolveUnknown(resource, context)
}
}
}
}
100 changes: 100 additions & 0 deletions simbot-api/src/commonTest/kotlin/message/OfflineImageResolverTests.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright (c) 2024. ForteScarlet.
*
* Project https://github.com/simple-robot/simpler-robot
* Email ForteScarlet@163.com
*
* This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Lesser GNU General Public License for more details.
*
* You should have received a copy of the Lesser GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/

package message

import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.test.runTest
import love.forte.simbot.message.OfflineByteArrayImage
import love.forte.simbot.message.OfflineImage
import love.forte.simbot.message.OfflineImage.Companion.toOfflineImage
import love.forte.simbot.message.OfflineImageResolver
import love.forte.simbot.message.OfflineImageResolver.Companion.resolve
import love.forte.simbot.message.OfflineResourceImage
import love.forte.simbot.resource.Resource
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.test.Test
import kotlin.test.assertEquals


/**
*
* @author ForteScarlet
*/
class OfflineImageResolverTests {
private enum class Value {
UKN,
BA,
R
}

@Test
fun offlineImageTest() = runTest {
val resolver = object : OfflineImageResolver<Continuation<Value>> {
override fun resolveUnknown(image: OfflineImage, context: Continuation<Value>) {
context.resume(Value.UKN)
}

override fun resolveByteArray(image: OfflineByteArrayImage, context: Continuation<Value>) {
context.resume(Value.BA)
}

override fun resolveResource(image: OfflineResourceImage, context: Continuation<Value>) {
context.resume(Value.R)
}
}
assertEquals(
Value.UKN,
suspendCancellableCoroutine { c ->
resolver.resolve(
object : OfflineImage {
override fun data(): ByteArray = byteArrayOf()
},
c
)
}
)
assertEquals(
Value.BA,
suspendCancellableCoroutine { c ->
resolver.resolve(
byteArrayOf().toOfflineImage(),
c
)
}
)
assertEquals(
Value.R,
suspendCancellableCoroutine { c ->
resolver.resolve(
object : Resource {
override fun data(): ByteArray = byteArrayOf()
}.toOfflineImage(),
c
)
}
)
}

}
Loading

0 comments on commit 402f8af

Please sign in to comment.