Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions buildSrc/src/main/kotlin/P.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ fun isSnapshot(): Boolean = _isSnapshot
@Suppress("MemberVisibilityCanBePrivate")
sealed class P(override val group: String) : ProjectDetail() {
companion object {
const val VERSION = "4.9.0"
const val NEXT_VERSION = "4.9.1"
const val VERSION = "4.10.0"
const val NEXT_VERSION = "4.10.0"
const val SNAPSHOT_VERSION = "$VERSION-SNAPSHOT"
const val NEXT_SNAPSHOT_VERSION = "$NEXT_VERSION-SNAPSHOT"

Expand Down
39 changes: 31 additions & 8 deletions simbot-api/api/simbot-api.api
Original file line number Diff line number Diff line change
Expand Up @@ -2195,11 +2195,15 @@ public abstract interface class love/forte/simbot/message/OfflineImage : love/fo
public static final field Companion Llove/forte/simbot/message/OfflineImage$Companion;
public abstract fun data ()[B
public static fun ofBytes ([B)Llove/forte/simbot/message/OfflineImage;
public static fun ofFilePath (Ljava/lang/String;)Llove/forte/simbot/message/OfflineImage;
public static fun ofFilePath (Ljava/lang/String;[Ljava/lang/String;)Llove/forte/simbot/message/OfflineImage;
public static fun ofResource (Llove/forte/simbot/resource/Resource;)Llove/forte/simbot/message/OfflineImage;
}

public final class love/forte/simbot/message/OfflineImage$Companion {
public final fun ofBytes ([B)Llove/forte/simbot/message/OfflineImage;
public final fun ofFilePath (Ljava/lang/String;)Llove/forte/simbot/message/OfflineImage;
public final fun ofFilePath (Ljava/lang/String;[Ljava/lang/String;)Llove/forte/simbot/message/OfflineImage;
public final fun ofResource (Llove/forte/simbot/resource/Resource;)Llove/forte/simbot/message/OfflineImage;
}

Expand Down Expand Up @@ -2528,14 +2532,15 @@ public abstract class love/forte/simbot/resource/AbstractJvmResourceValueResolve
public final fun resolveURI (Llove/forte/simbot/resource/URIResource;Ljava/lang/Object;)V
}

public abstract interface class love/forte/simbot/resource/ByteArrayResource : love/forte/simbot/resource/Resource {
public abstract interface class love/forte/simbot/resource/ByteArrayResource : love/forte/simbot/resource/Resource, love/forte/simbot/resource/SourceResource {
public abstract fun data ()[B
public fun source ()Lkotlinx/io/Source;
}

public abstract interface annotation class love/forte/simbot/resource/ExperimentalIOResourceAPI : java/lang/annotation/Annotation {
}

public abstract interface class love/forte/simbot/resource/FileResource : love/forte/simbot/resource/InputStreamResource, love/forte/simbot/resource/ReaderResource {
public abstract interface class love/forte/simbot/resource/FileResource : love/forte/simbot/resource/InputStreamResource, love/forte/simbot/resource/JvmSourceResource, love/forte/simbot/resource/ReaderResource {
public fun data ()[B
public abstract fun getFile ()Ljava/io/File;
public fun inputStream ()Ljava/io/InputStream;
Expand All @@ -2545,9 +2550,8 @@ public abstract interface class love/forte/simbot/resource/FileResource : love/f
public abstract fun string (Ljava/nio/charset/Charset;)Ljava/lang/String;
}

public abstract interface class love/forte/simbot/resource/InputStreamResource : love/forte/simbot/resource/Resource {
public fun data ()[B
public abstract fun inputStream ()Ljava/io/InputStream;
public abstract interface class love/forte/simbot/resource/InputStreamResource : love/forte/simbot/resource/SourceResource {
public fun inputStream ()Ljava/io/InputStream;
}

public abstract interface class love/forte/simbot/resource/JvmResourceResolver : love/forte/simbot/resource/ResourceResolver {
Expand All @@ -2572,6 +2576,9 @@ public abstract interface class love/forte/simbot/resource/JvmResourceValueResol
public abstract fun resolveURINotFileScheme (Ljava/net/URI;Ljava/lang/Object;)V
}

public abstract interface class love/forte/simbot/resource/JvmSourceResource : love/forte/simbot/resource/SourceResource {
}

public abstract interface class love/forte/simbot/resource/JvmStringReadableResource : love/forte/simbot/resource/StringReadableResource {
public static final field Companion Llove/forte/simbot/resource/JvmStringReadableResource$Companion;
public static final field DEFAULT_CHARSET Ljava/nio/charset/Charset;
Expand All @@ -2582,7 +2589,7 @@ public abstract interface class love/forte/simbot/resource/JvmStringReadableReso
public final class love/forte/simbot/resource/JvmStringReadableResource$Companion {
}

public abstract interface class love/forte/simbot/resource/PathResource : love/forte/simbot/resource/InputStreamResource, love/forte/simbot/resource/ReaderResource {
public abstract interface class love/forte/simbot/resource/PathResource : love/forte/simbot/resource/InputStreamResource, love/forte/simbot/resource/JvmSourceResource, love/forte/simbot/resource/ReaderResource {
public fun data ()[B
public abstract fun getPath ()Ljava/nio/file/Path;
public abstract fun inputStream ()Ljava/io/InputStream;
Expand Down Expand Up @@ -2622,6 +2629,7 @@ public final class love/forte/simbot/resource/ResourceResolver$Companion {
}

public final class love/forte/simbot/resource/Resources {
public static final fun inputStream (Llove/forte/simbot/resource/SourceResource;)Ljava/io/InputStream;
public static final fun valueOf (Ljava/io/File;)Llove/forte/simbot/resource/FileResource;
public static final fun valueOf (Ljava/io/File;Ljava/nio/charset/Charset;)Llove/forte/simbot/resource/FileResource;
public static final fun valueOf (Ljava/lang/String;)Llove/forte/simbot/resource/StringResource;
Expand All @@ -2631,22 +2639,37 @@ public final class love/forte/simbot/resource/Resources {
public static final fun valueOf (Ljava/net/URL;Ljava/nio/charset/Charset;)Llove/forte/simbot/resource/URIResource;
public static final fun valueOf (Ljava/nio/file/Path;Ljava/nio/charset/Charset;[Ljava/nio/file/OpenOption;)Llove/forte/simbot/resource/PathResource;
public static final fun valueOf (Ljava/nio/file/Path;[Ljava/nio/file/OpenOption;)Llove/forte/simbot/resource/PathResource;
public static final fun valueOf (Lkotlinx/io/files/Path;)Llove/forte/simbot/resource/SourceResource;
public static final fun valueOf ([B)Llove/forte/simbot/resource/ByteArrayResource;
public static synthetic fun valueOf$default (Ljava/io/File;Ljava/nio/charset/Charset;ILjava/lang/Object;)Llove/forte/simbot/resource/FileResource;
public static synthetic fun valueOf$default (Ljava/net/URI;Ljava/nio/charset/Charset;ILjava/lang/Object;)Llove/forte/simbot/resource/URIResource;
public static synthetic fun valueOf$default (Ljava/net/URL;Ljava/nio/charset/Charset;ILjava/lang/Object;)Llove/forte/simbot/resource/URIResource;
public static synthetic fun valueOf$default (Ljava/nio/file/Path;Ljava/nio/charset/Charset;[Ljava/nio/file/OpenOption;ILjava/lang/Object;)Llove/forte/simbot/resource/PathResource;
public static final fun valueOfInputStreamProvider (Lkotlin/jvm/functions/Function0;)Llove/forte/simbot/resource/SourceResource;
public static final fun valueOfPath (Ljava/lang/String;)Llove/forte/simbot/resource/SourceResource;
public static final fun valueOfPath (Ljava/lang/String;[Ljava/lang/String;)Llove/forte/simbot/resource/SourceResource;
public static final fun valueOfSourceProvider (Lkotlin/jvm/functions/Function0;)Llove/forte/simbot/resource/SourceResource;
}

public abstract interface class love/forte/simbot/resource/StringReadableResource : love/forte/simbot/resource/Resource {
public abstract interface annotation class love/forte/simbot/resource/ScheduledDeprecatedResourceApi : java/lang/annotation/Annotation {
}

public abstract interface class love/forte/simbot/resource/SourceResource : love/forte/simbot/resource/Resource {
public fun data ()[B
public abstract fun source ()Lkotlinx/io/Source;
}

public abstract interface class love/forte/simbot/resource/StringReadableResource : love/forte/simbot/resource/SourceResource {
public fun data ()[B
public fun source ()Lkotlinx/io/Source;
public abstract fun string ()Ljava/lang/String;
}

public abstract interface class love/forte/simbot/resource/StringResource : love/forte/simbot/resource/StringReadableResource {
public abstract fun string ()Ljava/lang/String;
}

public abstract interface class love/forte/simbot/resource/URIResource : love/forte/simbot/resource/InputStreamResource, love/forte/simbot/resource/JvmStringReadableResource {
public abstract interface class love/forte/simbot/resource/URIResource : love/forte/simbot/resource/InputStreamResource, love/forte/simbot/resource/JvmSourceResource, love/forte/simbot/resource/JvmStringReadableResource {
public abstract fun getUri ()Ljava/net/URI;
public abstract fun inputStream ()Ljava/io/InputStream;
public fun string ()Ljava/lang/String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,8 @@

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.*
import love.forte.simbot.resource.ResourceResolver.Companion.resolve
import love.forte.simbot.resource.StringResource
import kotlin.jvm.JvmStatic


Expand Down Expand Up @@ -76,6 +73,7 @@ public interface OfflineImageResolver<C> {
* 继承 [OfflineImageResolver] 和 [ResourceResolver],
* 对其中可能出现的实际内容物(例如 [ByteArray] 或 [String])进行处理。
*/
@ScheduledDeprecatedResourceApi
public interface OfflineImageValueResolver<C> :
OfflineImageResolver<C>,
ResourceResolver<C> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,14 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import love.forte.simbot.common.id.ID
import love.forte.simbot.common.id.IDContainer
import love.forte.simbot.message.At.Companion.equals
import love.forte.simbot.message.At.Companion.hashCode
import love.forte.simbot.message.OfflineImage.Companion.toOfflineImage
import love.forte.simbot.message.Text.Companion.of
import love.forte.simbot.resource.*
import love.forte.simbot.resource.ByteArrayResource
import love.forte.simbot.resource.Resource
import love.forte.simbot.resource.ResourceBase64Serializer
import love.forte.simbot.resource.fileResource
import kotlin.io.encoding.ExperimentalEncodingApi
import kotlin.js.JsName
import kotlin.jvm.*
Expand Down Expand Up @@ -297,12 +302,16 @@ public interface UrlAwareImage : Image, UrlAwareMessage {
*
* “离线”主要表示此图片并未上传到某个目标平台中,也没有与某个远程服务器互相对应的唯一标识。
*
* @see OfflineImage.toOfflineImage
* 离线图片消息由本地构建,不会来自远端服务器或事件内。
* 离线图片消息无法保证可序列化性,尽可能避免对其进行序列化(包括作为 [Messages] 的元素时)。
*
* @see ByteArray.toOfflineImage
* @see Resource.toOfflineImage
*
* @see OfflineByteArrayImage
* @see SimpleOfflineResourceImage
* @see OfflineResourceImage
*/
public interface OfflineImage : Image {
public sealed interface OfflineImage : Image {
/**
* 得到图片的二进制数据
*/
Expand Down Expand Up @@ -348,7 +357,6 @@ public interface OfflineImage : Image {
*/
@JvmStatic
@JvmName("ofFilePath")
@ExperimentalIOResourceAPI
public fun fileOfflineImage(filePath: String): OfflineImage =
fileResource(filePath).toOfflineResourceImage()

Expand All @@ -363,7 +371,6 @@ public interface OfflineImage : Image {
* @since 4.7.0
*/
@JvmStatic
@ExperimentalIOResourceAPI
@JvmName("ofFilePath")
public fun fileOfflineImage(base: String, vararg parts: String): OfflineImage =
fileResource(base, *parts).toOfflineResourceImage()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

package love.forte.simbot.resource

import kotlinx.io.Buffer
import kotlinx.io.Source
import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
Expand All @@ -46,6 +48,17 @@ import kotlin.jvm.JvmName
* JVM 中的部分扩展、辅助API通过静态类 `Resources` 提供,
* 例如 `Resources.valueOf(...)`。
*
* ## 有限范围
*
* 从 `v4.10.0` 开始,[Resource] 接口转为 `sealed` 并有两个明确的子类型分支:
* - [ByteArrayResource]
* - [SourceResource]
*
* [ByteArrayResource] 代表一个可以**直接**使用 [ByteArray] 进行表示的资源,它也同样可以表示为 [SourceResource]。
*
* 其中,[SourceResource] 借助 `kotlinx-io` 库所提供的能力统一多平台的IO相关API(例如文件系统相关)。
* 如果你想要基于文件系统或其他与IO相关的内容构建一个 [Resource],则参考 [SourceResource]。
*
* ## 序列化
*
* [Resource] 提供了一个基于 [Base64] 进行序列化操作的 [ResourceBase64Serializer]。
Expand All @@ -59,9 +72,7 @@ import kotlin.jvm.JvmName
*
* @author ForteScarlet
*/
public interface Resource {
// TODO become `sealed` for ByteArrayResource and SourceResource.

public sealed interface Resource {
/**
* 读取此资源的字节数据。
*
Expand All @@ -83,11 +94,15 @@ public fun ByteArray.toResource(): ByteArrayResource = ByteArrayResourceImpl(thi
*
* @author forte
*/
public interface ByteArrayResource : Resource {
public interface ByteArrayResource : Resource, SourceResource {
/**
* 获取到字节数组结果。
*/
override fun data(): ByteArray

override fun source(): Source {
return Buffer().apply { write(data()) }
}
}

/**
Expand Down Expand Up @@ -147,12 +162,18 @@ private data class ByteArrayResourceImpl(private val raw: ByteArray) : ByteArray
* 一个可以读取到 [String] 内容物的拓展类型。
* 是其他 [Resource] 类型的附加能力,但不属于一个标准的 [Resource] 类型。
*/
public interface StringReadableResource : Resource {
public interface StringReadableResource : SourceResource {
/**
* 读取此资源的 [String] 内容。
*/
@Throws(Exception::class)
public fun string(): String

override fun data(): ByteArray = string().encodeToByteArray()

override fun source(): Source {
return Buffer().apply { write(data()) }
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,23 @@

package love.forte.simbot.resource

import kotlin.annotation.AnnotationRetention.BINARY
import kotlin.annotation.AnnotationTarget.CLASS
import kotlin.annotation.AnnotationTarget.FUNCTION
import kotlin.jvm.JvmStatic

/**
* 计划被废弃的与 [Resource] 相关的API
*/
@RequiresOptIn(
message = "计划被废弃的与 `Resource` 相关的API. 详见 " +
"`love.forte.simbot.resource.ResourceResolver` 和 " +
"`love.forte.simbot.resource.Resource` 中的有关说明。"
)
@Retention(BINARY)
@Target(CLASS, FUNCTION)
@MustBeDocumented
public annotation class ScheduledDeprecatedResourceApi

/**
* 使用 [ResourceResolver] 分析处理一个 [Resource].
Expand All @@ -33,8 +48,14 @@ import kotlin.jvm.JvmStatic
*
* 在 JVM 平台会提供一个具有更多能力的类型。
*
* Note: 由于[Resource]现在已经通过 `sealed` 限制了子类型范围,
* 因此可以直接使用 [ByteArrayResource] 或 [SourceResource]。
* 得益于 `kotlinx-io`,明确 resolve 多平台(尤其是JVM平台)下的独特类型的情况已经不多了。
* [ResourceResolver] 可能会在未来废弃, 且现在开始不再建议使用。
*
* @author ForteScarlet
*/
@ScheduledDeprecatedResourceApi
public interface ResourceResolver<C> {
/**
* 处理一个未知的 [Resource] 类型的 resource.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ public annotation class ExperimentalIOResourceAPI
* @since 4.7.0
*/
@JvmName("valueOfPath")
@ExperimentalIOResourceAPI
public fun fileResource(filePath: String): SourceResource {
return Path(filePath).toResource()
}
Expand All @@ -94,7 +93,6 @@ public fun fileResource(filePath: String): SourceResource {
* @since 4.7.0
*/
@JvmName("valueOfPath")
@ExperimentalIOResourceAPI
public fun fileResource(base: String, vararg parts: String): SourceResource {
return Path(base, *parts).toResource()
}
Expand All @@ -110,19 +108,36 @@ public fun fileResource(base: String, vararg parts: String): SourceResource {
* @since 4.8.0
*/
@JvmName("valueOf")
@ExperimentalIOResourceAPI
public fun Path.toResource(): SourceResource {
return FilePathResource(this)
}

/**
* 提供一个用于产生 [Source] 的供应函数 [provider],
* 并得到一个 [SourceResource]。
*
* 得到的结果每次使用 [SourceResource.source] 都会通过 [provider]
* 获取一个 [Source]。[Source] 应当由使用者决定关闭时机,而不是在 [provider] 中。
*
* @since 4.10.0
*/
@JvmName("valueOfSourceProvider")
public fun sourceResource(provider: () -> Source): SourceResource {
return SourceResourceImpl(provider)
}


/**
* 一个可以得到 [kotlinx.io.Source] 的 [Resource]。
*
* 在 JVM 平台中 `Resources` 中会提供更多基于JVM文件系统构建 [SourceResource] 的 API。
*
* @see fileResource
* @see sourceResource
* @see Path.toResource
*
* @since 4.7.0
*/
@ExperimentalIOResourceAPI
public interface SourceResource : Resource {
/**
* 得到一个用于本次数据读取的 [Source].
Expand Down Expand Up @@ -154,7 +169,6 @@ public interface SourceResource : Resource {
override fun data(): ByteArray = source().use { it.readByteArray() }
}

@ExperimentalIOResourceAPI
private data class FilePathResource(val path: Path) : SourceResource {
private val source
get() = SystemFileSystem.source(path)
Expand All @@ -163,3 +177,9 @@ private data class FilePathResource(val path: Path) : SourceResource {
override fun source(): Source = source.buffered()
}

/**
* @since 4.10.0
*/
private data class SourceResourceImpl(val provider: () -> Source) : SourceResource {
override fun source(): Source = provider()
}
Loading
Loading