Skip to content

Commit

Permalink
nullable limits in suppliers
Browse files Browse the repository at this point in the history
  • Loading branch information
lukellmann committed Feb 2, 2022
1 parent 88625d0 commit 965e9df
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 170 deletions.
32 changes: 16 additions & 16 deletions core/src/main/kotlin/behavior/GuildScheduledEventBehavior.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ import dev.kord.common.entity.DiscordGuildScheduledEvent
import dev.kord.common.entity.Snowflake
import dev.kord.common.exception.RequestException
import dev.kord.core.Kord
import dev.kord.core.cache.data.UserData
import dev.kord.core.entity.*
import dev.kord.core.exception.EntityNotFoundException
import dev.kord.core.supplier.EntitySupplier
import dev.kord.core.supplier.EntitySupplyStrategy
import dev.kord.rest.builder.scheduled_events.ScheduledEventModifyBuilder
import dev.kord.rest.service.modifyScheduledEvent
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

Expand All @@ -28,26 +26,28 @@ public interface GuildScheduledEventBehavior : KordEntity, Strategizable {
*
* @throws RequestException if anything goes wrong during the request
*/

public val users: Flow<User>
get() = supplier.getGuildScheduledEventUsers(guildId, id)

public fun getGuildScheduledEventUsersAfter(
limit: Int = Int.MAX_VALUE,
after: Snowflake = Snowflake.min
): Flow<User> = supplier.getGuildScheduledEventUsersAfter(guildId, id, limit, after)
public fun getGuildScheduledEventUsersAfter(after: Snowflake = Snowflake.min, limit: Int? = null): Flow<User> =
supplier.getGuildScheduledEventUsersAfter(guildId, id, after, limit)

public fun getGuildScheduledEventUsersBefore(before: Snowflake = Snowflake.max, limit: Int? = null): Flow<User> =
supplier.getGuildScheduledEventUsersBefore(guildId, id, before, limit)

public fun getGuildScheduledEventUsersBefore(
limit: Int = Int.MAX_VALUE,
before: Snowflake = Snowflake.max
): Flow<User> = supplier.getGuildScheduledEventUsersBefore(guildId, id, limit, before)
public val members: Flow<Member>
get() = supplier.getGuildScheduledEventMembers(guildId, id)

public fun getGuildScheduledEventMembersAfter(limit: Int = Int.MAX_VALUE, after: Snowflake = Snowflake.min): Flow<Member> =
supplier.getGuildScheduledEventMembersAfter(guildId, id, limit, after)
public fun getGuildScheduledEventMembersAfter(
after: Snowflake = Snowflake.min,
limit: Int? = null,
): Flow<Member> = supplier.getGuildScheduledEventMembersAfter(guildId, id, after, limit)

public fun getGuildScheduledEventMembersBefore(
before: Snowflake = Snowflake.max,
limit: Int? = null,
): Flow<Member> = supplier.getGuildScheduledEventMembersBefore(guildId, id, before, limit)

public fun getGuildScheduledEventMembersBefore(limit: Int = Int.MAX_VALUE, before: Snowflake = Snowflake.max): Flow<Member> =
supplier.getGuildScheduledEventMembersBefore(guildId, id, limit, before)
/**
* Deletes this event.
*
Expand Down Expand Up @@ -81,7 +81,7 @@ public interface GuildScheduledEventBehavior : KordEntity, Strategizable {
public suspend fun fetchGuildScheduledEvent(): GuildScheduledEvent = supplier.getGuildScheduledEvent(guildId, id)

/**
* Fetches to get the this behavior as a [Guild],
* Fetches to get this behavior as a [Guild],
* returns null if the event isn't present.
*
* @throws [RequestException] if anything went wrong during the request.
Expand Down
73 changes: 36 additions & 37 deletions core/src/main/kotlin/supplier/CacheEntitySupplier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -476,59 +476,58 @@ public class CacheEntitySupplier(private val kord: Kord) : EntitySupplier {
override fun getGuildScheduledEventMembersBefore(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
before: Snowflake
before: Snowflake,
limit: Int?,
): Flow<Member> {
val flow = cache.query<MemberData> {
idLt(MemberData::userId, before)
idEq(MemberData::guildId, guildId)
}.asFlow().mapNotNull {
val userData = cache.query<UserData> {
idEq(UserData::id, it.userId)

}.singleOrNull() ?: return@mapNotNull null
Member(it, userData, kord)
}
return if (limit != Int.MAX_VALUE) flow.take(limit) else flow
checkLimit(limit)
return cache
.query<MemberData> {
idLt(MemberData::userId, before)
idEq(MemberData::guildId, guildId)
}
.asFlow()
.mapNotNull {
val userData = cache.query<UserData> { idEq(UserData::id, it.userId) }.singleOrNull()
?: return@mapNotNull null
Member(it, userData, kord)
}
.limit(limit)
}

override fun getGuildScheduledEventUsersBefore(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
before: Snowflake
): Flow<User> {
return getGuildScheduledEventMembersBefore(guildId, eventId, limit, before).map { it.asUser() }
}
before: Snowflake,
limit: Int?,
): Flow<User> = getGuildScheduledEventMembersBefore(guildId, eventId, before, limit).map { it.asUser() }

override fun getGuildScheduledEventMembersAfter(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
after: Snowflake
after: Snowflake,
limit: Int?,
): Flow<Member> {
val flow = cache.query<MemberData> {
idGt(MemberData::userId, after)
idEq(MemberData::guildId, guildId)
}.asFlow().mapNotNull {
val userData = cache.query<UserData> {
idEq(UserData::id, it.userId)

}.singleOrNull() ?: return@mapNotNull null
Member(it, userData, kord)
}
return if (limit != Int.MAX_VALUE) flow.take(limit) else flow
checkLimit(limit)
return cache
.query<MemberData> {
idGt(MemberData::userId, after)
idEq(MemberData::guildId, guildId)
}
.asFlow()
.mapNotNull {
val userData = cache.query<UserData> { idEq(UserData::id, it.userId) }.singleOrNull()
?: return@mapNotNull null
Member(it, userData, kord)
}
.limit(limit)
}


override fun getGuildScheduledEventUsersAfter(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
after: Snowflake
): Flow<User> {
return getGuildScheduledEventMembersAfter(guildId, eventId, limit, after).map { it.asUser() }
}
after: Snowflake,
limit: Int?,
): Flow<User> = getGuildScheduledEventMembersAfter(guildId, eventId, after, limit).map { it.asUser() }

override suspend fun getStickerOrNull(id: Snowflake): Sticker? {
val data = cache.query<StickerData> { idEq(StickerData::id, id) }.singleOrNull() ?: return null
Expand Down
35 changes: 18 additions & 17 deletions core/src/main/kotlin/supplier/EntitySupplier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -559,41 +559,42 @@ public interface EntitySupplier {
public suspend fun getGuildScheduledEvent(guildId: Snowflake, eventId: Snowflake): GuildScheduledEvent =
getGuildScheduledEventOrNull(guildId, eventId) ?: EntityNotFoundException.guildScheduledEventNotFound(eventId)

public fun getGuildScheduledEventUsersBefore(

public fun getGuildScheduledEventUsers(guildId: Snowflake, eventId: Snowflake, limit: Int? = null): Flow<User> =
getGuildScheduledEventUsersAfter(guildId, eventId, after = Snowflake.min, limit)

public fun getGuildScheduledEventUsersBefore(
guildId: Snowflake,
eventId: Snowflake,
limit: Int = Int.MAX_VALUE,
before: Snowflake = Snowflake.max
before: Snowflake,
limit: Int? = null,
): Flow<User>


public fun getGuildScheduledEventUsersAfter(
guildId: Snowflake,
eventId: Snowflake,
limit: Int = Int.MAX_VALUE,
after: Snowflake = Snowflake.min
after: Snowflake,
limit: Int? = null,
): Flow<User>

public fun getGuildScheduledEventMembersBefore(

public fun getGuildScheduledEventMembers(guildId: Snowflake, eventId: Snowflake, limit: Int? = null): Flow<Member> =
getGuildScheduledEventMembersAfter(guildId, eventId, after = Snowflake.min, limit)

public fun getGuildScheduledEventMembersBefore(
guildId: Snowflake,
eventId: Snowflake,
limit: Int = Int.MAX_VALUE,
before: Snowflake = Snowflake.max
before: Snowflake,
limit: Int? = null,
): Flow<Member>


public fun getGuildScheduledEventMembersAfter(
guildId: Snowflake,
eventId: Snowflake,
limit: Int = Int.MAX_VALUE,
after: Snowflake = Snowflake.min
after: Snowflake,
limit: Int? = null,
): Flow<Member>

public fun getGuildScheduledEventUsers(
guildId: Snowflake,
eventId: Snowflake,
limit: Int = Int.MAX_VALUE,
): Flow<User> = getGuildScheduledEventUsersAfter(guildId, eventId, limit)

public suspend fun getStickerOrNull(id: Snowflake): Sticker?

Expand Down
33 changes: 16 additions & 17 deletions core/src/main/kotlin/supplier/FallbackEntitySupplier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -220,39 +220,38 @@ private class FallbackEntitySupplier(val first: EntitySupplier, val second: Enti
override fun getGuildScheduledEventUsersBefore(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
before: Snowflake
before: Snowflake,
limit: Int?,
): Flow<User> =
first.getGuildScheduledEventUsersBefore(guildId, eventId, limit, before)
.switchIfEmpty(second.getGuildScheduledEventUsersBefore(guildId, eventId, limit, before))
first.getGuildScheduledEventUsersBefore(guildId, eventId, before, limit)
.switchIfEmpty(second.getGuildScheduledEventUsersBefore(guildId, eventId, before, limit))

override fun getGuildScheduledEventUsersAfter(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
after: Snowflake
after: Snowflake,
limit: Int?,
): Flow<User> =
first.getGuildScheduledEventUsersAfter(guildId, eventId, limit, after)
.switchIfEmpty(second.getGuildScheduledEventUsersAfter(guildId, eventId, limit, after))

first.getGuildScheduledEventUsersAfter(guildId, eventId, after, limit)
.switchIfEmpty(second.getGuildScheduledEventUsersAfter(guildId, eventId, after, limit))

override fun getGuildScheduledEventMembersBefore(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
before: Snowflake
before: Snowflake,
limit: Int?,
): Flow<Member> =
first.getGuildScheduledEventMembersBefore(guildId, eventId, limit, before)
.switchIfEmpty(second.getGuildScheduledEventMembersBefore(guildId, eventId, limit, before))
first.getGuildScheduledEventMembersBefore(guildId, eventId, before, limit)
.switchIfEmpty(second.getGuildScheduledEventMembersBefore(guildId, eventId, before, limit))

override fun getGuildScheduledEventMembersAfter(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
after: Snowflake
after: Snowflake,
limit: Int?,
): Flow<Member> =
first.getGuildScheduledEventMembersAfter(guildId, eventId, limit, after)
.switchIfEmpty(second.getGuildScheduledEventMembersAfter(guildId, eventId, limit, after))
first.getGuildScheduledEventMembersAfter(guildId, eventId, after, limit)
.switchIfEmpty(second.getGuildScheduledEventMembersAfter(guildId, eventId, after, limit))

override suspend fun getStickerOrNull(id: Snowflake): Sticker? =
first.getStickerOrNull(id) ?: second.getStickerOrNull(id)
Expand Down
83 changes: 36 additions & 47 deletions core/src/main/kotlin/supplier/RestEntitySupplier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -477,80 +477,69 @@ public class RestEntitySupplier(public val kord: Kord) : EntitySupplier {
override fun getGuildScheduledEventUsersBefore(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
before: Snowflake
): Flow<User> {
return getGuildScheduledEventUsersBefore(guildId, eventId, limit, false, before).map {
val data = UserData.from(it.user)
User(data, kord)
}
before: Snowflake,
limit: Int?,
): Flow<User> = getGuildScheduledEventUsersBefore(guildId, eventId, before, withMember = false, limit).map {
val data = UserData.from(it.user)
User(data, kord)
}

override fun getGuildScheduledEventUsersAfter(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
after: Snowflake
): Flow<User> {
return getGuildScheduledEventUsersAfter(guildId, eventId, limit, false, after).map {
val data = UserData.from(it.user)
User(data, kord)
}
after: Snowflake,
limit: Int?,
): Flow<User> = getGuildScheduledEventUsersAfter(guildId, eventId, after, withMember = false, limit).map {
val data = UserData.from(it.user)
User(data, kord)
}

override fun getGuildScheduledEventMembersBefore(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
before: Snowflake
): Flow<Member> {
return getGuildScheduledEventUsersBefore(guildId, eventId, limit,true, before).map {
val data = UserData.from(it.user)
val memberData = it.member.value!!.toData(data.id, guildId)
Member(memberData, data, kord)
}
before: Snowflake,
limit: Int?,
): Flow<Member> = getGuildScheduledEventUsersBefore(guildId, eventId, before, withMember = true, limit).map {
val userData = UserData.from(it.user)
val memberData = it.member.value!!.toData(userData.id, guildId)
Member(memberData, userData, kord)
}

override fun getGuildScheduledEventMembersAfter(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
after: Snowflake
): Flow<Member> {
return getGuildScheduledEventUsersAfter(guildId, eventId, limit,true, after).map {
val data = UserData.from(it.user)
val memberData = it.member.value!!.toData(data.id, guildId)
Member(memberData, data, kord)
}
after: Snowflake,
limit: Int?,
): Flow<Member> = getGuildScheduledEventUsersAfter(guildId, eventId, after, withMember = true, limit).map {
val userData = UserData.from(it.user)
val memberData = it.member.value!!.toData(userData.id, guildId)
Member(memberData, userData, kord)
}

// maxBatchSize: see https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event-users
private fun getGuildScheduledEventUsersBefore(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
withMember: Boolean?,
before: Snowflake
): Flow<GuildScheduledEventUsersResponse> {
val batch = min(100, limit)
return paginateBackwards(batch, before, { it.user.id }) { position ->
kord.rest.guild.getScheduledEventUsers(guildId, eventId, batch, withMember, position)
before: Snowflake,
withMember: Boolean,
limit: Int?,
): Flow<GuildScheduledEventUsersResponse> = limitedPagination(limit, maxBatchSize = 100) { batchSize ->
paginateBackwards(batchSize, start = before, idSelector = { it.user.id }) { beforePosition ->
guild.getScheduledEventUsers(guildId, eventId, beforePosition, withMember, limit = batchSize)
}

}

// maxBatchSize: see https://discord.com/developers/docs/resources/guild-scheduled-event#get-guild-scheduled-event-users
private fun getGuildScheduledEventUsersAfter(
guildId: Snowflake,
eventId: Snowflake,
limit: Int,
withMember: Boolean?,
after: Snowflake
): Flow<GuildScheduledEventUsersResponse> {

val batch = min(100, limit)
return paginateForwards(batch, after, { it.user.id }) { position ->
kord.rest.guild.getScheduledEventUsers(guildId, eventId, batch, withMember, position)
after: Snowflake,
withMember: Boolean,
limit: Int?,
): Flow<GuildScheduledEventUsersResponse> = limitedPagination(limit, maxBatchSize = 100) { batchSize ->
paginateForwards(batchSize, start = after, idSelector = { it.user.id }) { afterPosition ->
guild.getScheduledEventUsers(guildId, eventId, afterPosition, withMember, limit = batchSize)
}

}

override suspend fun getStickerOrNull(id: Snowflake): Sticker? = catchNotFound {
Expand Down
Loading

0 comments on commit 965e9df

Please sign in to comment.