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

Unify permission overwrite API (Fix #302) #420

Merged
Merged
Show file tree
Hide file tree
Changes from 2 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
10 changes: 8 additions & 2 deletions common/src/main/kotlin/entity/optional/Optional.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package dev.kord.common.entity.optional

import dev.kord.common.entity.Snowflake
import dev.kord.common.entity.optional.Optional.*
import dev.kord.common.entity.optional.Optional.Missing
import dev.kord.common.entity.optional.Optional.Null
import dev.kord.common.entity.optional.Optional.OptionalSerializer
import dev.kord.common.entity.optional.Optional.Value
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
Expand Down Expand Up @@ -128,6 +131,9 @@ sealed class Optional<out T> {
if (value.isEmpty()) Missing()
else Value(value)

fun <T, C : Collection<T>> missingOnEmptyOrOnNull(value: C?): Optional<C> =
if (value == null) Missing() else missingOnEmpty(value)

/**
* Returns a [Missing] optional of type [T].
*/
Expand Down Expand Up @@ -304,7 +310,7 @@ fun <T : Any> T.optional(): Optional.Value<T> = Optional.Value(this)

fun <T : Any?> T?.optional(): Optional<T?> = Optional(this)

fun Optional<Boolean>.toPrimitive() : OptionalBoolean = when(this){
fun Optional<Boolean>.toPrimitive(): OptionalBoolean = when (this) {
is Value -> OptionalBoolean.Value(value)
else -> OptionalBoolean.Missing
}
38 changes: 6 additions & 32 deletions rest/src/main/kotlin/builder/channel/CategoryCreateBuilder.kt
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
package dev.kord.rest.builder.channel

import dev.kord.common.annotation.KordDsl
import dev.kord.common.entity.ChannelType
import dev.kord.common.entity.Overwrite
import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.common.annotation.KordDsl
import dev.kord.common.entity.OverwriteType
import dev.kord.common.entity.Snowflake
import dev.kord.common.entity.optional.Optional
import dev.kord.common.entity.optional.OptionalBoolean
import dev.kord.common.entity.optional.OptionalInt
import dev.kord.common.entity.optional.delegate.delegate
import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.rest.json.request.GuildChannelCreateRequest
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

@KordDsl
class CategoryCreateBuilder(var name: String) : AuditRequestBuilder<GuildChannelCreateRequest> {
class CategoryCreateBuilder(var name: String) : PermissionOverritesBuilder, AuditRequestBuilder<GuildChannelCreateRequest> {
override var reason: String? = null

private var _position: OptionalInt = OptionalInt.Missing
Expand All @@ -25,35 +20,14 @@ class CategoryCreateBuilder(var name: String) : AuditRequestBuilder<GuildChannel
private var _nsfw: OptionalBoolean = OptionalBoolean.Missing
var nsfw: Boolean? by ::_nsfw.delegate()

val permissionOverwrites: MutableList<Overwrite> = mutableListOf()

/**
* adds a [Overwrite] for the [memberId].
*/
@OptIn(ExperimentalContracts::class)
inline fun addMemberOverwrite(memberId: Snowflake, builder: PermissionOverwriteBuilder.() -> Unit) {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}
permissionOverwrites += PermissionOverwriteBuilder(OverwriteType.Member, memberId).apply(builder).toOverwrite()
}

/**
* adds a [Overwrite] for the [roleId].
*/
@OptIn(ExperimentalContracts::class)
inline fun addRoleOverwrite(roleId: Snowflake, builder: PermissionOverwriteBuilder.() -> Unit) {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}
permissionOverwrites += PermissionOverwriteBuilder(OverwriteType.Role, roleId).apply(builder).toOverwrite()
}
private var _permissionOverwrites: Optional<MutableSet<Overwrite>> = Optional.Missing()
override var permissionOverwrites by ::_permissionOverwrites.delegate()

override fun toRequest(): GuildChannelCreateRequest = GuildChannelCreateRequest(
name = name,
position = _position,
nsfw = _nsfw,
permissionOverwrite = Optional.missingOnEmpty(permissionOverwrites),
permissionOverwrite = _permissionOverwrites,
type = ChannelType.GuildCategory
)
}
41 changes: 5 additions & 36 deletions rest/src/main/kotlin/builder/channel/CategoryModifyBuilder.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
package dev.kord.rest.builder.channel

import dev.kord.common.entity.Overwrite
import dev.kord.common.entity.Snowflake
import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.common.annotation.KordDsl
import dev.kord.common.entity.OverwriteType
import dev.kord.common.entity.Overwrite
import dev.kord.common.entity.optional.Optional
import dev.kord.common.entity.optional.OptionalInt
import dev.kord.common.entity.optional.delegate.delegate
import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.rest.json.request.ChannelModifyPatchRequest
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

@KordDsl
class CategoryModifyBuilder : AuditRequestBuilder<ChannelModifyPatchRequest> {
class CategoryModifyBuilder : PermissionOverritesBuilder, AuditRequestBuilder<ChannelModifyPatchRequest> {

override var reason: String? = null

Expand All @@ -37,37 +32,11 @@ class CategoryModifyBuilder : AuditRequestBuilder<ChannelModifyPatchRequest> {
/**
* The permission overwrites for this category.
*/
var permissionOverwrites: MutableSet<Overwrite>? by ::_permissionOverwrites.delegate()

/**
* adds a [Overwrite] for the [memberId].
*/
@OptIn(ExperimentalContracts::class)
inline fun addMemberOverwrite(memberId: Snowflake, builder: PermissionOverwriteBuilder.() -> Unit) {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}
val overwrite = permissionOverwrites ?: mutableSetOf()
overwrite.add(PermissionOverwriteBuilder(OverwriteType.Member, memberId).apply(builder).toOverwrite())
permissionOverwrites = overwrite
}

/**
* adds a [Overwrite] for the [roleId].
*/
@OptIn(ExperimentalContracts::class)
inline fun addRoleOverwrite(roleId: Snowflake, builder: PermissionOverwriteBuilder.() -> Unit) {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}
val overwrite = permissionOverwrites ?: mutableSetOf()
overwrite.add(PermissionOverwriteBuilder(OverwriteType.Role, roleId).apply(builder).toOverwrite())
permissionOverwrites = overwrite
}
override var permissionOverwrites by ::_permissionOverwrites.delegate()

override fun toRequest(): ChannelModifyPatchRequest = ChannelModifyPatchRequest(
name = _name,
position = _position,
permissionOverwrites = _permissionOverwrites
)
}
}
12 changes: 6 additions & 6 deletions rest/src/main/kotlin/builder/channel/EditGuildChannelBuilder.kt
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package dev.kord.rest.builder.channel

import dev.kord.common.annotation.KordDsl
import dev.kord.common.entity.Overwrite
import dev.kord.common.entity.Snowflake
import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.common.annotation.KordDsl
import dev.kord.common.entity.optional.Optional
import dev.kord.common.entity.optional.OptionalBoolean
import dev.kord.common.entity.optional.OptionalInt
import dev.kord.common.entity.optional.OptionalSnowflake
import dev.kord.common.entity.optional.delegate.delegate
import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.rest.json.request.ChannelModifyPatchRequest

@KordDsl
class TextChannelModifyBuilder : AuditRequestBuilder<ChannelModifyPatchRequest> {
class TextChannelModifyBuilder : PermissionOverritesBuilder,
AuditRequestBuilder<ChannelModifyPatchRequest> {
override var reason: String? = null

private var _name: Optional<String> = Optional.Missing()
Expand All @@ -33,16 +34,15 @@ class TextChannelModifyBuilder : AuditRequestBuilder<ChannelModifyPatchRequest>
private var _rateLimitPerUser: OptionalInt? = OptionalInt.Missing
var rateLimitPerUser: Int? by ::_rateLimitPerUser.delegate()

private var _permissionOverwrites: Optional<MutableSet<Overwrite>?> = Optional.Missing()
var permissionOverwrites: MutableSet<Overwrite>? by ::_permissionOverwrites.delegate()
override var permissionOverwrites: MutableSet<Overwrite>? = mutableSetOf()

override fun toRequest(): ChannelModifyPatchRequest = ChannelModifyPatchRequest(
name = _name,
position = _position,
topic = _topic,
nsfw = _nsfw,
rateLimitPerUser = _rateLimitPerUser,
permissionOverwrites = _permissionOverwrites,
permissionOverwrites = Optional.missingOnEmptyOrOnNull(permissionOverwrites),
parentId = _parentId
)

Expand Down
15 changes: 8 additions & 7 deletions rest/src/main/kotlin/builder/channel/NewsChannelCreateBuilder.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package dev.kord.rest.builder.channel

import dev.kord.common.entity.Overwrite
import dev.kord.common.entity.Snowflake
import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.common.annotation.KordDsl
import dev.kord.common.entity.ChannelType
import dev.kord.common.entity.Overwrite
import dev.kord.common.entity.Snowflake
import dev.kord.common.entity.optional.Optional
import dev.kord.common.entity.optional.OptionalBoolean
import dev.kord.common.entity.optional.OptionalInt
import dev.kord.common.entity.optional.OptionalSnowflake
import dev.kord.common.entity.optional.delegate.delegate
import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.rest.json.request.GuildChannelCreateRequest

@KordDsl
class NewsChannelCreateBuilder(var name: String) : AuditRequestBuilder<GuildChannelCreateRequest> {
class NewsChannelCreateBuilder(var name: String) : PermissionOverritesBuilder,
AuditRequestBuilder<GuildChannelCreateRequest> {
override var reason: String? = null

private var _topic: Optional<String> = Optional.Missing()
Expand All @@ -28,15 +29,15 @@ class NewsChannelCreateBuilder(var name: String) : AuditRequestBuilder<GuildChan
private var _position: OptionalInt = OptionalInt.Missing
var position: Int? by ::_position.delegate()

val permissionOverwrites: MutableList<Overwrite> = mutableListOf()
override var permissionOverwrites: MutableSet<Overwrite>? = mutableSetOf()

override fun toRequest(): GuildChannelCreateRequest = GuildChannelCreateRequest(
name = name,
topic = _topic,
nsfw = _nsfw,
parentId = _parentId,
position = _position,
permissionOverwrite = Optional.missingOnEmpty(permissionOverwrites),
DRSchlaubi marked this conversation as resolved.
Show resolved Hide resolved
permissionOverwrite = Optional.missingOnEmptyOrOnNull(permissionOverwrites),
type = ChannelType.GuildNews
)
}
}
44 changes: 44 additions & 0 deletions rest/src/main/kotlin/builder/channel/PermissionOverritesBuilder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package dev.kord.rest.builder.channel

import dev.kord.common.entity.Overwrite
import dev.kord.common.entity.OverwriteType
import dev.kord.common.entity.Snowflake
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

/**
* Interface containing shared behavior on all builders modifying permission overwrites.
DRSchlaubi marked this conversation as resolved.
Show resolved Hide resolved
*/
interface PermissionOverritesBuilder {
DRSchlaubi marked this conversation as resolved.
Show resolved Hide resolved
/**
* The permission overwrites for this category.
*/
var permissionOverwrites: MutableSet<Overwrite>?
}

/**
* adds a [Overwrite] for the [memberId].
DRSchlaubi marked this conversation as resolved.
Show resolved Hide resolved
*/
@OptIn(ExperimentalContracts::class)
inline fun PermissionOverritesBuilder.addMemberOverwrite(memberId: Snowflake, builder: PermissionOverwriteBuilder.() -> Unit) {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}
val overwrite = permissionOverwrites ?: mutableSetOf()
overwrite.add(PermissionOverwriteBuilder(OverwriteType.Member, memberId).apply(builder).toOverwrite())
permissionOverwrites = overwrite
}

/**
* adds a [Overwrite] for the [roleId].
DRSchlaubi marked this conversation as resolved.
Show resolved Hide resolved
*/
@OptIn(ExperimentalContracts::class)
inline fun PermissionOverritesBuilder.addRoleOverwrite(roleId: Snowflake, builder: PermissionOverwriteBuilder.() -> Unit) {
contract {
callsInPlace(builder, InvocationKind.EXACTLY_ONCE)
}
val overwrite = permissionOverwrites ?: mutableSetOf()
overwrite.add(PermissionOverwriteBuilder(OverwriteType.Role, roleId).apply(builder).toOverwrite())
permissionOverwrites = overwrite
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.rest.json.request.GuildChannelCreateRequest

@KordDsl
class TextChannelCreateBuilder(var name: String) : AuditRequestBuilder<GuildChannelCreateRequest> {
class TextChannelCreateBuilder(var name: String) : PermissionOverritesBuilder, AuditRequestBuilder<GuildChannelCreateRequest> {
override var reason: String? = null

private var _topic: Optional<String> = Optional.Missing()
Expand All @@ -31,7 +31,7 @@ class TextChannelCreateBuilder(var name: String) : AuditRequestBuilder<GuildChan
private var _nsfw: OptionalBoolean = OptionalBoolean.Missing
var nsfw: Boolean? by ::_nsfw.delegate()

val permissionOverwrites: MutableList<Overwrite> = mutableListOf()
override var permissionOverwrites: MutableSet<Overwrite>? = mutableSetOf()

override fun toRequest(): GuildChannelCreateRequest = GuildChannelCreateRequest(
name,
Expand All @@ -41,6 +41,6 @@ class TextChannelCreateBuilder(var name: String) : AuditRequestBuilder<GuildChan
_position,
parentId = _parentId,
nsfw = _nsfw,
permissionOverwrite = Optional.missingOnEmpty(permissionOverwrites),
permissionOverwrite = Optional.missingOnEmptyOrOnNull(permissionOverwrites),
)
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package dev.kord.rest.builder.channel

import dev.kord.common.annotation.KordDsl
import dev.kord.common.entity.ChannelType
import dev.kord.common.entity.Overwrite
import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.common.annotation.KordDsl
import dev.kord.common.entity.Snowflake
import dev.kord.common.entity.optional.Optional
import dev.kord.common.entity.optional.OptionalInt
import dev.kord.common.entity.optional.OptionalSnowflake
import dev.kord.common.entity.optional.delegate.delegate
import dev.kord.rest.builder.AuditRequestBuilder
import dev.kord.rest.json.request.GuildChannelCreateRequest

@KordDsl
class VoiceChannelCreateBuilder(var name: String) : AuditRequestBuilder<GuildChannelCreateRequest> {
class VoiceChannelCreateBuilder(var name: String) :
PermissionOverritesBuilder, AuditRequestBuilder<GuildChannelCreateRequest> {
override var reason: String? = null

private var _bitrate: OptionalInt = OptionalInt.Missing
Expand All @@ -27,15 +28,15 @@ class VoiceChannelCreateBuilder(var name: String) : AuditRequestBuilder<GuildCha
private var _position: OptionalInt = OptionalInt.Missing
var position: Int? by ::_position.delegate()

val permissionOverwrites: MutableList<Overwrite> = mutableListOf()
override var permissionOverwrites: MutableSet<Overwrite>? = mutableSetOf()
DRSchlaubi marked this conversation as resolved.
Show resolved Hide resolved

override fun toRequest(): GuildChannelCreateRequest = GuildChannelCreateRequest(
name = name,
bitrate = _bitrate,
userLimit = _userLimit,
parentId = _parentId,
position = _position,
permissionOverwrite = Optional.missingOnEmpty(permissionOverwrites),
permissionOverwrite = Optional.missingOnEmptyOrOnNull(permissionOverwrites),
type = ChannelType.GuildVoice
)
}
}
Loading