diff --git a/core/src/main/kotlin/supplier/CacheEntitySupplier.kt b/core/src/main/kotlin/supplier/CacheEntitySupplier.kt index 3eb1dbbc987f..1e71c275e502 100644 --- a/core/src/main/kotlin/supplier/CacheEntitySupplier.kt +++ b/core/src/main/kotlin/supplier/CacheEntitySupplier.kt @@ -198,9 +198,13 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { return Ban(data, kord) } - override fun getGuildBans(guildId: Snowflake): Flow = cache.query { - idEq(BanData::guildId, guildId) - }.asFlow().map { Ban(it, kord) } + override fun getGuildBans(guildId: Snowflake, limit: Int?): Flow { + checkLimit(limit) + return cache.query { idEq(BanData::guildId, guildId) } + .asFlow() + .map { Ban(it, kord) } + .limit(limit) + } override fun getGuildMembers(guildId: Snowflake, limit: Int?): Flow { checkLimit(limit) diff --git a/core/src/main/kotlin/supplier/EntitySupplier.kt b/core/src/main/kotlin/supplier/EntitySupplier.kt index 30a0c03942b6..d8622c2db17e 100644 --- a/core/src/main/kotlin/supplier/EntitySupplier.kt +++ b/core/src/main/kotlin/supplier/EntitySupplier.kt @@ -288,7 +288,7 @@ public interface EntitySupplier { * The returned flow is lazily executed, any [RequestException] will be thrown on * [terminal operators](https://kotlinlang.org/docs/reference/coroutines/flow.html#terminal-flow-operators) instead. */ - public fun getGuildBans(guildId: Snowflake): Flow + public fun getGuildBans(guildId: Snowflake, limit: Int? = null): Flow /** * Requests the [members][Member] of the [Guild] with the given [guildId]. diff --git a/core/src/main/kotlin/supplier/FallbackEntitySupplier.kt b/core/src/main/kotlin/supplier/FallbackEntitySupplier.kt index 08267d5493a0..ec46362ef4cc 100644 --- a/core/src/main/kotlin/supplier/FallbackEntitySupplier.kt +++ b/core/src/main/kotlin/supplier/FallbackEntitySupplier.kt @@ -76,8 +76,8 @@ private class FallbackEntitySupplier(val first: EntitySupplier, val second: Enti override suspend fun getGuildBanOrNull(guildId: Snowflake, userId: Snowflake): Ban? = first.getGuildBanOrNull(guildId, userId) ?: second.getGuildBanOrNull(guildId, userId) - override fun getGuildBans(guildId: Snowflake): Flow = - first.getGuildBans(guildId).switchIfEmpty(second.getGuildBans(guildId)) + override fun getGuildBans(guildId: Snowflake, limit: Int?): Flow = + first.getGuildBans(guildId, limit).switchIfEmpty(second.getGuildBans(guildId, limit)) override fun getGuildMembers(guildId: Snowflake, limit: Int?): Flow = first.getGuildMembers(guildId, limit).switchIfEmpty(second.getGuildMembers(guildId, limit)) diff --git a/core/src/main/kotlin/supplier/RestEntitySupplier.kt b/core/src/main/kotlin/supplier/RestEntitySupplier.kt index 090872e4ba90..4738727fd9a6 100644 --- a/core/src/main/kotlin/supplier/RestEntitySupplier.kt +++ b/core/src/main/kotlin/supplier/RestEntitySupplier.kt @@ -161,10 +161,16 @@ public class RestEntitySupplier(public val kord: Kord) : EntitySupplier { emit(Role(RoleData.from(guildId, roleData), kord)) } - override fun getGuildBans(guildId: Snowflake): Flow = flow { - for (banData in guild.getGuildBans(guildId)) - emit(Ban(BanData.from(guildId, banData), kord)) - } + // maxBatchSize: see https://discord.com/developers/docs/resources/guild#get-guild-bans + override fun getGuildBans(guildId: Snowflake, limit: Int?): Flow = + limitedPagination(limit, maxBatchSize = 1000) { batchSize -> + paginateForwards(batchSize, idSelector = { it.user.id }) { after -> + guild.getGuildBans(guildId, position = after, limit = batchSize) + } + }.map { + val data = BanData.from(guildId, it) + Ban(data, kord) + } // maxBatchSize: see https://discord.com/developers/docs/resources/guild#list-guild-members override fun getGuildMembers(guildId: Snowflake, limit: Int?): Flow = diff --git a/core/src/main/kotlin/supplier/StoreEntitySupplier.kt b/core/src/main/kotlin/supplier/StoreEntitySupplier.kt index ef54a66ee040..e4b802575398 100644 --- a/core/src/main/kotlin/supplier/StoreEntitySupplier.kt +++ b/core/src/main/kotlin/supplier/StoreEntitySupplier.kt @@ -108,8 +108,8 @@ public class StoreEntitySupplier( return storeAndReturn(supplier.getGuildBanOrNull(guildId, userId)) { it.data } } - override fun getGuildBans(guildId: Snowflake): Flow { - return storeOnEach(supplier.getGuildBans(guildId)) { it.data } + override fun getGuildBans(guildId: Snowflake, limit: Int?): Flow { + return storeOnEach(supplier.getGuildBans(guildId, limit)) { it.data } } override fun getGuildMembers(guildId: Snowflake, limit: Int?): Flow { diff --git a/rest/src/main/kotlin/service/GuildService.kt b/rest/src/main/kotlin/service/GuildService.kt index fc6db61f537f..99696fefd0fa 100644 --- a/rest/src/main/kotlin/service/GuildService.kt +++ b/rest/src/main/kotlin/service/GuildService.kt @@ -192,8 +192,15 @@ public class GuildService(requestHandler: RequestHandler) : RestService(requestH auditLogReason(reason) } - public suspend fun getGuildBans(guildId: Snowflake): List = call(Route.GuildBansGet) { + public suspend fun getGuildBans( + guildId: Snowflake, + position: Position.BeforeOrAfter? = null, + limit: Int? = null, + ): List = call(Route.GuildBansGet) { keys[Route.GuildId] = guildId + + limit?.let { parameter("limit", it) } + position?.let { parameter(it.key, it.value) } } public suspend fun getGuildBan(guildId: Snowflake, userId: Snowflake): BanResponse = call(Route.GuildBanGet) {