Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

调整 FriendsContainer.friendCount, ContactsContainer.contactCount, GroupsContainer.groupCount, GuildsContainer.guildCount 的默认行为和语义 #644

Merged
merged 1 commit into from
Apr 11, 2023
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
51 changes: 33 additions & 18 deletions buildSrc/src/main/kotlin/P.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@

@file:Suppress("unused")

import love.forte.gradle.common.core.project.*
import love.forte.gradle.common.core.project.ProjectDetail
import love.forte.gradle.common.core.project.Version
import love.forte.gradle.common.core.project.minus
import love.forte.gradle.common.core.project.version

/*
* Copyright (c) 2021-2022 ForteScarlet <ForteScarlet@163.com>
Expand All @@ -36,10 +39,10 @@ inline fun isSnapshot(b: () -> Unit = {}): Boolean {
b()
val snapProp = System.getProperty("isSnapshot")?.toBoolean() ?: false
val snapEnv = System.getenv(Env.IS_SNAPSHOT)?.toBoolean() ?: false

println("IsSnapshot from system.property: $snapProp")
println("IsSnapshot from system.env: $snapEnv")

return snapProp || snapEnv
}

Expand All @@ -58,39 +61,51 @@ sealed class P(override val group: String) : ProjectDetail() {
const val BOOT_GROUP = "love.forte.simbot.boot"
const val TEST_GROUP = "love.forte.simbot.test"
const val UTIL_GROUP = "love.forte.simbot.util"

// const val COMPONENT_GROUP = "love.forte.simbot.component"
const val DESCRIPTION = "Simple Robot,一个通用的bot风格事件调度框架,以灵活的统一标准来编写bot应用。"
const val HOMEPAGE = "https://github.com/simple-robot/simpler-robot"

fun findProjectDetailByGroup(group: String): ProjectDetail? {
val groupProject =
P::class.sealedSubclasses.mapNotNull { it.objectInstance }.associateBy { obj -> obj.group }
return groupProject[group]
}

}

override val homepage: String get() = HOMEPAGE

object Simbot : P(GROUP)
object SimbotBoot : P(BOOT_GROUP)
object SimbotTest : P(TEST_GROUP)
object SimbotUtil : P(UTIL_GROUP)

final override val version: Version
val versionWithoutSnapshot: Version

init {
val mainVersion = version(3, 0, 0)
var status = version("RC", 3)
versionWithoutSnapshot = mainVersion - status.copy()
if (isSnapshot()) {
status -= Version.SNAPSHOT

fun initVersionWithoutSnapshot(status: Version?): Version = if (status == null) {
mainVersion
} else {
mainVersion - status.copy()
}
version = mainVersion - status

// versionWithoutSnapshot = initVersionWithoutSnapshot(version("RC", 3))
versionWithoutSnapshot = initVersionWithoutSnapshot(null)

version = if (isSnapshot()) {
versionWithoutSnapshot - Version.SNAPSHOT
} else {
versionWithoutSnapshot
}

println("version=$version, versionWithoutSnapshot=$versionWithoutSnapshot")
}



override val description: String get() = DESCRIPTION
override val developers: List<Developer> = developers {
developer {
Expand Down Expand Up @@ -121,6 +136,6 @@ sealed class P(override val group: String) : ProjectDetail() {
connection = "scm:git:$HOMEPAGE.git"
developerConnection = "scm:git:ssh://git@github.com/simple-robot/simpler-robot.git"
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@

package love.forte.simbot.definition

import kotlinx.coroutines.flow.count
import love.forte.simbot.ID
import love.forte.simbot.JST
import love.forte.simbot.JSTP
import love.forte.simbot.bot.Bot
import love.forte.simbot.definition.SocialRelationsContainer.Companion.COUNT_NOT_SUPPORTED
import love.forte.simbot.utils.item.Items

/**
Expand All @@ -30,7 +30,53 @@ import love.forte.simbot.utils.item.Items
* @see GroupsContainer
* @see GuildsContainer
*/
public sealed interface SocialRelationsContainer : SuspendablePropertyContainer
public sealed interface SocialRelationsContainer : SuspendablePropertyContainer {
public companion object {

/**
* 在 `xxxCount` 相关API中使用的常量信息,代表**不支持**此API。
*
* 以 [`guildCount`][GuildsContainer.guildCount] 为例:
* ```kotlin
* if (bot.guildCount() == SocialRelationsContainer.COUNT_NOT_SUPPORTED) {
* // 实际上此bot不支持直接获取 guild 总数量,需要考虑使用 bot.guilds 或其他方式获取。
* }
* ```
*
*/
public const val COUNT_NOT_SUPPORTED: Int = -1

/**
* 在 `xxxCount` 相关API中使用的常量信息,代表此API得到的结果为空。
*
* 通常用于在源码中明确表示此API得到的结果**始终为空**,常量本身不可用于直接作为判断比较。
* 此常量面向 [SocialRelationsContainer] 相关类型的实现者而不是使用者。
*
* **正例**
*
* 以 [`guildCount`][GuildsContainer.guildCount] 为例,某 [Bot] 的实现者在源码中宣告
* `guildCount` 不被支持,始终得到 `0`:
*
* ```kotlin
* class SomeBotImpl : Bot {
* override suspend fun guildCount(): Int = SocialRelationsContainer.COUNT_EMPTY
* // 需要再配套真正而全面的说明,比如标记 @Deprecated 注解和明确的文档注释等。
* }
* ```
*
* **反例**
*
* ```kotlin
* if (bot.guildCount() == SocialRelationsContainer.COUNT_EMPTY) {
* // 错误的认为 bot.guildCount 会始终得到 0
* }
* ```
*
*/
public const val COUNT_EMPTY: Int = 0

}
}


/**
Expand All @@ -44,10 +90,10 @@ public sealed interface SocialRelationsContainer : SuspendablePropertyContainer
* "好友"并 _**不一定**_ 代表那些需要 "添加申请"、"同意" 后出现在好友列表中的好友,
* 也并非所有的组件都支持“好友”的概念。
*
* 对于一个以"频道"概念为主的组件就是最常见的例子(例如Kook) —— 它们通常没有真正的"好友"概念,
* 至少对于bot来讲没有。取而代之的则通常是"频道成员"或者一个"会话"。
* 对于一个以"频道"概念为主的组件就是最常见的例子(例如KOOK) —— 它们通常没有真正的"好友"概念,
* 至少对于bot来讲没有。取而代之的则通常是"频道成员"或者一个"私聊会话"。
*
* 实际上,对于一个bot来讲"好友"的概念确实可有可无,它更需要"[联系人][Contact]"。
* 实际上,对于一个bot来讲 "[好友][Friend]" 的概念确实可有可无,它更需要 "[联系人][Contact]"
*
* 在一个容器同时支持 [FriendsContainer] 和 [ContactsContainer]
* 的情况下,[FriendsContainer] 中能够得到的目标常常为 [ContactsContainer]
Expand All @@ -57,38 +103,42 @@ public sealed interface SocialRelationsContainer : SuspendablePropertyContainer
*
*/
public interface FriendsContainer : SocialRelationsContainer {

/**
* 得到此容器下的好友序列。
*
* [friends] 可能是一个根据 [Items.batch] 批次发起某种网络请求的真实序列,
* 也可能是由当前容器内部提前缓存好的伪序列,而不会发起真正的网络请求。
*/
public val friends: Items<Friend>

/**
* 得到当前容器中所有[好友][Friend]的总数量。
*
* [friendCount] 可能每次请求都会发起某种网络请求,
* 也可能仅跟随当前容器内部某种缓存机制刷新的数值,而不会发起真正的网络请求。
*
* 默认情况下(组件未实现、不支持直接查询数量等)相当于直接通过 [friends] 进行全量查询并计数。
* [friendCount] 的结果大于等于0时有效,小于零时可能代表部分存在含义的常量:
*
* - [COUNT_NOT_SUPPORTED]: 不支持获取总数
*
* 默认情况下(未被子类实现或不支持)会得到 [COUNT_NOT_SUPPORTED] 以表示 [friendCount] 的结果无效。
*
* @see COUNT_NOT_SUPPORTED
*
* @since 3.0.0-RC.2
*/
@JSTP
public suspend fun friendCount(): Int {
return friends.asFlow().count()
}

public suspend fun friendCount(): Int = COUNT_NOT_SUPPORTED

/**
* 通过唯一标识获取这个容器对应的某个好友,获取不到则为null。
*
* @param id 好友的唯一标识
*/
@JST(blockingBaseName = "getFriend", blockingSuffix = "", asyncBaseName = "getFriend")
public suspend fun friend(id: ID): Friend?

}


Expand All @@ -102,15 +152,15 @@ public interface FriendsContainer : SocialRelationsContainer {
* 或者存在一个被创建过的"会话"(例如某联系人主动与bot进行过交流或者
* 与当前容器([Bot])创建过与某个目标的会话)。
*
* 因上述约束,[ContactsContainer.contacts] 通常不具备检索 组织成员 [Member]
* 因上述约束,[ContactsContainer.contacts] 通常不具备检索 [组织成员][Member]
* 这类**间接**联系人的能力, 尽管 [Member] 也属于 [Contact] 类型 ———— 除非它们与当前容器存在**直接**会话。
*
* 当一个bot中,所有可能的联系人都是与bot存在硬性关系(例如它们之间是 [好友][Friend] 关系)的时候,
* [ContactsContainer] 的表现将会与 [FriendsContainer] 类似。
*
*/
public interface ContactsContainer : SocialRelationsContainer {

/**
* 是否支持contacts相关的获取操作。当 [contacts] 和 [contact] 都不被支持时得到 `false`。
* 默认情况下视其为 `true`,由实现者重写此属性来决定其可用性。
Expand All @@ -121,7 +171,7 @@ public interface ContactsContainer : SocialRelationsContainer {
*
*/
public val isContactsSupported: Boolean get() = true

/**
* 得到当前容器中能够获取到的联系人序列。
*
Expand All @@ -141,23 +191,27 @@ public interface ContactsContainer : SocialRelationsContainer {
*
*/
public val contacts: Items<Contact>


/**
* 得到当前容器中所有[联系人][Contact]的总数量。
*
* [contactCount] 可能每次请求都会发起某种网络请求,
* 也可能仅跟随当前容器内部某种缓存机制刷新的数值,而不会发起真正的网络请求。
*
* 默认情况下(组件未实现、不支持直接查询数量等)相当于直接通过 [contacts] 进行全量查询并计数。
* [contactCount] 的结果大于等于0时有效,小于零时可能代表部分存在含义的常量:
*
* - [COUNT_NOT_SUPPORTED]: 不支持获取总数
*
* 默认情况下(未被子类实现或不支持)会得到 [COUNT_NOT_SUPPORTED] 以表示 [contactCount] 的结果无效。
*
* @see COUNT_NOT_SUPPORTED
*
* @since 3.0.0-RC.2
*/
@JSTP
public suspend fun contactCount(): Int {
return contacts.asFlow().count()
}

public suspend fun contactCount(): Int = COUNT_NOT_SUPPORTED

/**
* 通过唯一标识获取对应的 [Contact] 实例。当且仅当因标识对应联系人不存在而导致无法获取时得到null。
*
Expand All @@ -179,7 +233,7 @@ public interface ContactsContainer : SocialRelationsContainer {
*
*/
public interface GroupsContainer : SocialRelationsContainer {

/**
* 是否支持groups相关的获取操作。当 [groups] 和 [group] 都不被支持时得到 `false`。
* 默认情况下视其为 `true`,由实现者重写此属性来决定其可用性。
Expand All @@ -190,7 +244,7 @@ public interface GroupsContainer : SocialRelationsContainer {
*
*/
public val isGroupsSupported: Boolean get() = true

/**
* 获取当前bot所处的群聊序列。
*
Expand All @@ -199,22 +253,24 @@ public interface GroupsContainer : SocialRelationsContainer {
*
*/
public val groups: Items<Group>

/**
* 得到当前容器中所有[群][Group]的总数量。
*
* [groupCount] 可能每次请求都会发起某种网络请求,
* 也可能仅跟随当前容器内部某种缓存机制刷新的数值,而不会发起真正的网络请求。
*
* 默认情况下(组件未实现、不支持直接查询数量等)相当于直接通过 [groups] 进行全量查询并计数。
* [groupCount] 的结果大于等于0时有效,小于零时可能代表部分存在含义的常量:
* - [COUNT_NOT_SUPPORTED]: 不支持获取总数
*
* 默默认情况下(未被子类实现或不支持)会得到 [COUNT_NOT_SUPPORTED] 以表示 [groupCount] 的结果无效。
*
* @see COUNT_NOT_SUPPORTED
* @since 3.0.0-RC.2
*/
@JSTP
public suspend fun groupCount(): Int {
return groups.asFlow().count()
}

public suspend fun groupCount(): Int = COUNT_NOT_SUPPORTED

/**
* 通过唯一标识获取这个bot对应的某个群,获取不到则为null。
*
Expand All @@ -232,7 +288,7 @@ public interface GroupsContainer : SocialRelationsContainer {
*
*/
public interface GuildsContainer : SocialRelationsContainer {

/**
* 是否支持guilds相关的获取操作。当 [guilds] 和 [guild] 都不被支持时得到 `false`。
* 默认情况下视其为 `true`,由实现者重写此属性来决定其可用性。
Expand All @@ -243,30 +299,32 @@ public interface GuildsContainer : SocialRelationsContainer {
*
*/
public val isGuildsSupported: Boolean get() = true

/**
* 获取当前的所有频道服务器序列。
*
* [guilds] 可能是一个根据 [Items.batch] 批次发起某种网络请求的真实序列,
* 也可能是由当前容器内部提前缓存好的伪序列,而不会发起真正的网络请求。
*/
public val guilds: Items<Guild>

/**
* 得到当前容器中所有[频道服务器][Guild]的总数量。
*
* [guildCount] 可能每次请求都会发起某种网络请求,
* 也可能仅跟随当前容器内部某种缓存机制刷新的数值,而不会发起真正的网络请求。
*
* 默认情况下(组件未实现、不支持直接查询数量等)相当于直接通过 [guilds] 进行全量查询并计数。
* [guildCount] 的结果大于等于0时有效,小于零时可能代表部分存在含义的常量:
* - [COUNT_NOT_SUPPORTED]: 不支持获取总数
*
* 默认情况下(未被子类实现或不支持)会得到 [COUNT_NOT_SUPPORTED] 以表示 [guildCount] 的结果无效。
*
* @see COUNT_NOT_SUPPORTED
* @since 3.0.0-RC.2
*/
@JSTP
public suspend fun guildCount(): Int {
return guilds.asFlow().count()
}

public suspend fun guildCount(): Int = COUNT_NOT_SUPPORTED

/**
* 通过唯一标识获取这个bot对应的某个频道,获取不到则为null。
*
Expand Down
2 changes: 1 addition & 1 deletion website