From 52dc82ac04efde10c9bd2c2693d15b33a08f1bbc Mon Sep 17 00:00:00 2001 From: BartArys Date: Sun, 6 Dec 2020 17:11:10 +0100 Subject: [PATCH 01/90] Fix nullability in builders --- .../main/kotlin/entity/optional/Optional.kt | 9 +++- .../builder/channel/CategoryModifyBuilder.kt | 16 ++++-- .../channel/EditGuildChannelBuilder.kt | 52 ++++++++++--------- .../GuildChannelPositionModifyBuilder.kt | 8 ++- .../builder/guild/EmojiModifyBuilder.kt | 5 +- .../builder/guild/GuildModifyBuilder.kt | 24 ++++----- .../builder/member/MemberModifyBuilder.kt | 13 ++--- .../kotlin/builder/role/RoleModifyBuilder.kt | 10 ++-- .../builder/user/CurrentUserModifyBuilder.kt | 2 +- .../builder/webhook/WebhookModifyBuilder.kt | 2 +- .../main/kotlin/json/request/EmojiRequests.kt | 4 +- .../main/kotlin/json/request/GuildRequests.kt | 32 ++++++------ 12 files changed, 100 insertions(+), 77 deletions(-) diff --git a/common/src/main/kotlin/entity/optional/Optional.kt b/common/src/main/kotlin/entity/optional/Optional.kt index 9955efeba21..d934a1e487a 100644 --- a/common/src/main/kotlin/entity/optional/Optional.kt +++ b/common/src/main/kotlin/entity/optional/Optional.kt @@ -213,11 +213,18 @@ inline fun Optional>.mapList(mapper: (E) -> T): Optional> } @Suppress("UNCHECKED_CAST") -inline fun Optional.map(mapper: (E) -> T): Optional = when (this) { +inline fun Optional.map(mapper: (E) -> T): Optional = when (this) { is Missing, is Null<*> -> this as Optional is Value -> Value(mapper(value)) } +@Suppress("UNCHECKED_CAST") +@JvmName("mapNullableOptional") +inline fun Optional.map(mapper: (E) -> T): Optional = when (this) { + is Missing, is Null<*> -> this as Optional + is Value -> Value(mapper(value!!)) +} + @Suppress("UNCHECKED_CAST") inline fun Optional.mapNullable(mapper: (E) -> T): Optional = when (this) { is Missing, is Null<*> -> this as Optional diff --git a/rest/src/main/kotlin/builder/channel/CategoryModifyBuilder.kt b/rest/src/main/kotlin/builder/channel/CategoryModifyBuilder.kt index a8789abe1cc..db32642565c 100644 --- a/rest/src/main/kotlin/builder/channel/CategoryModifyBuilder.kt +++ b/rest/src/main/kotlin/builder/channel/CategoryModifyBuilder.kt @@ -24,17 +24,19 @@ class CategoryModifyBuilder: AuditRequestBuilder { */ var name: String? by ::_name.delegate() - private var _position: OptionalInt = OptionalInt.Missing + private var _position: OptionalInt? = OptionalInt.Missing /** * The position of this category in the guild's channel list. */ var position: Int? by ::_position.delegate() + private var _permissionOverwrites: Optional?> = Optional.Missing() + /** * The permission overwrites for this category. */ - var permissionOverwrites: MutableSet = mutableSetOf() + var permissionOverwrites: MutableSet? by ::_permissionOverwrites.delegate() /** * adds a [Overwrite] for the [memberId]. @@ -44,7 +46,9 @@ class CategoryModifyBuilder: AuditRequestBuilder { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - permissionOverwrites.add(PermissionOverwriteBuilder(OverwriteType.Member, memberId).apply(builder).toOverwrite()) + val overwrite = permissionOverwrites ?: mutableSetOf() + overwrite.add(PermissionOverwriteBuilder(OverwriteType.Member, memberId).apply(builder).toOverwrite()) + permissionOverwrites = overwrite } /** @@ -55,12 +59,14 @@ class CategoryModifyBuilder: AuditRequestBuilder { contract { callsInPlace(builder, InvocationKind.EXACTLY_ONCE) } - permissionOverwrites.add(PermissionOverwriteBuilder(OverwriteType.Role, roleId).apply(builder).toOverwrite()) + val overwrite = permissionOverwrites ?: mutableSetOf() + overwrite.add(PermissionOverwriteBuilder(OverwriteType.Role, roleId).apply(builder).toOverwrite()) + permissionOverwrites = overwrite } override fun toRequest(): ChannelModifyPatchRequest = ChannelModifyPatchRequest( name = _name, position = _position, - permissionOverwrites = Optional.missingOnEmpty(permissionOverwrites) + permissionOverwrites = _permissionOverwrites ) } \ No newline at end of file diff --git a/rest/src/main/kotlin/builder/channel/EditGuildChannelBuilder.kt b/rest/src/main/kotlin/builder/channel/EditGuildChannelBuilder.kt index acbcb1ce212..2445f342bb5 100644 --- a/rest/src/main/kotlin/builder/channel/EditGuildChannelBuilder.kt +++ b/rest/src/main/kotlin/builder/channel/EditGuildChannelBuilder.kt @@ -18,22 +18,23 @@ class TextChannelModifyBuilder : AuditRequestBuilder private var _name: Optional = Optional.Missing() var name: String? by ::_name.delegate() - private var _position: OptionalInt = OptionalInt.Missing + private var _position: OptionalInt? = OptionalInt.Missing var position: Int? by ::_position.delegate() - private var _topic: Optional = Optional.Missing() + private var _topic: Optional = Optional.Missing() var topic: String? by ::_topic.delegate() - private var _nsfw: OptionalBoolean = OptionalBoolean.Missing + private var _nsfw: OptionalBoolean? = OptionalBoolean.Missing var nsfw: Boolean? by ::_nsfw.delegate() - private var _parentId: OptionalSnowflake = OptionalSnowflake.Missing + private var _parentId: OptionalSnowflake? = OptionalSnowflake.Missing var parentId: Snowflake? by ::_parentId.delegate() - private var _rateLimitPerUser: OptionalInt = OptionalInt.Missing + private var _rateLimitPerUser: OptionalInt? = OptionalInt.Missing var rateLimitPerUser: Int? by ::_rateLimitPerUser.delegate() - var permissionOverwrites: MutableSet = mutableSetOf() + private var _permissionOverwrites: Optional?> = Optional.Missing() + var permissionOverwrites: MutableSet? by ::_permissionOverwrites.delegate() override fun toRequest(): ChannelModifyPatchRequest = ChannelModifyPatchRequest( name = _name, @@ -41,7 +42,7 @@ class TextChannelModifyBuilder : AuditRequestBuilder topic = _topic, nsfw = _nsfw, rateLimitPerUser = _rateLimitPerUser, - permissionOverwrites = Optional.missingOnEmpty(permissionOverwrites), + permissionOverwrites = _permissionOverwrites, parentId = _parentId ) @@ -54,21 +55,22 @@ class VoiceChannelModifyBuilder : AuditRequestBuilder private var _name: Optional = Optional.Missing() var name: String? by ::_name.delegate() - private var _position: OptionalInt = OptionalInt.Missing + private var _position: OptionalInt? = OptionalInt.Missing var position: Int? by ::_position.delegate() - private var _topic: Optional = Optional.Missing() + private var _topic: Optional = Optional.Missing() var topic: String? by ::_topic.delegate() - private var _parentId: OptionalSnowflake = OptionalSnowflake.Missing + private var _parentId: OptionalSnowflake? = OptionalSnowflake.Missing var parentId: Snowflake? by ::_parentId.delegate() - var permissionOverwrites: MutableSet = mutableSetOf() + private var _permissionOverwrites: Optional?> = Optional.Missing() + var permissionOverwrites: MutableSet? by ::_permissionOverwrites.delegate() - private var _bitrate: OptionalInt = OptionalInt.Missing + private var _bitrate: OptionalInt? = OptionalInt.Missing var bitrate: Int? by ::_bitrate.delegate() - private var _userLimit: OptionalInt = OptionalInt.Missing + private var _userLimit: OptionalInt? = OptionalInt.Missing var userLimit: Int? by ::_userLimit.delegate() override fun toRequest(): ChannelModifyPatchRequest = ChannelModifyPatchRequest( @@ -78,7 +80,7 @@ class VoiceChannelModifyBuilder : AuditRequestBuilder bitrate = _bitrate, userLimit = _userLimit, topic = _topic, - permissionOverwrites = Optional.missingOnEmpty(permissionOverwrites) + permissionOverwrites = _permissionOverwrites ) } @@ -90,29 +92,30 @@ class NewsChannelModifyBuilder : AuditRequestBuilder private var _name: Optional = Optional.Missing() var name: String? by ::_name.delegate() - private var _position: OptionalInt = OptionalInt.Missing + private var _position: OptionalInt? = OptionalInt.Missing var position: Int? by ::_position.delegate() - private var _topic: Optional = Optional.Missing() + private var _topic: Optional = Optional.Missing() var topic: String? by ::_topic.delegate() - private var _nsfw: OptionalBoolean = OptionalBoolean.Missing + private var _nsfw: OptionalBoolean? = OptionalBoolean.Missing var nsfw: Boolean? by ::_nsfw.delegate() - private var _parentId: OptionalSnowflake = OptionalSnowflake.Missing + private var _parentId: OptionalSnowflake? = OptionalSnowflake.Missing var parentId: Snowflake? by ::_parentId.delegate() - private var _rateLimitPerUser: OptionalInt = OptionalInt.Missing + private var _rateLimitPerUser: OptionalInt? = OptionalInt.Missing var rateLimitPerUser: Int? by ::_rateLimitPerUser.delegate() - var permissionOverwrites: MutableSet = mutableSetOf() + private var _permissionOverwrites: Optional?> = Optional.Missing() + var permissionOverwrites: MutableSet? by ::_permissionOverwrites.delegate() override fun toRequest(): ChannelModifyPatchRequest = ChannelModifyPatchRequest( name = _name, position = _position, topic = _topic, nsfw = _nsfw, - permissionOverwrites = Optional.missingOnEmpty(permissionOverwrites), + permissionOverwrites = _permissionOverwrites, parentId = _parentId ) } @@ -124,15 +127,16 @@ class StoreChannelModifyBuilder : AuditRequestBuilder private var _name: Optional = Optional.Missing() var name: String? by ::_name.delegate() - private var _position: OptionalInt = OptionalInt.Missing + private var _position: OptionalInt? = OptionalInt.Missing var position: Int? by ::_position.delegate() - var permissionOverwrites: MutableSet = mutableSetOf() + private var _permissionOverwrites: Optional?> = Optional.Missing() + var permissionOverwrites: MutableSet? by ::_permissionOverwrites.delegate() override fun toRequest(): ChannelModifyPatchRequest = ChannelModifyPatchRequest( name = _name, position = _position, - permissionOverwrites = Optional.missingOnEmpty(permissionOverwrites) + permissionOverwrites = _permissionOverwrites ) } \ No newline at end of file diff --git a/rest/src/main/kotlin/builder/channel/GuildChannelPositionModifyBuilder.kt b/rest/src/main/kotlin/builder/channel/GuildChannelPositionModifyBuilder.kt index 748766b9f65..f71799fe9fe 100644 --- a/rest/src/main/kotlin/builder/channel/GuildChannelPositionModifyBuilder.kt +++ b/rest/src/main/kotlin/builder/channel/GuildChannelPositionModifyBuilder.kt @@ -4,6 +4,8 @@ import dev.kord.rest.builder.AuditRequestBuilder import dev.kord.common.annotation.KordDsl import dev.kord.common.annotation.KordExperimental import dev.kord.common.entity.Snowflake +import dev.kord.common.entity.optional.OptionalInt +import dev.kord.common.entity.optional.delegate.delegate import dev.kord.rest.json.request.ChannelPositionSwapRequest import dev.kord.rest.json.request.GuildChannelPositionModifyRequest @@ -33,10 +35,12 @@ class GuildChannelPositionModifyBuilder: AuditRequestBuilder { private var _name: Optional = Optional.Missing() var name: String? by ::_name.delegate() - var roles: MutableSet = mutableSetOf() + private var _roles: Optional?> = Optional.Missing() + var roles: MutableSet? by ::_roles.delegate() override fun toRequest(): EmojiModifyRequest = EmojiModifyRequest( name = _name, - roles = Optional.missingOnEmpty(roles) + roles = _roles ) } \ No newline at end of file diff --git a/rest/src/main/kotlin/builder/guild/GuildModifyBuilder.kt b/rest/src/main/kotlin/builder/guild/GuildModifyBuilder.kt index 7e62c247d99..2ba4b3b4853 100644 --- a/rest/src/main/kotlin/builder/guild/GuildModifyBuilder.kt +++ b/rest/src/main/kotlin/builder/guild/GuildModifyBuilder.kt @@ -22,53 +22,53 @@ class GuildModifyBuilder : AuditRequestBuilder { private var _name: Optional = Optional.Missing() var name: String? by ::_name.delegate() - private var _region: Optional = Optional.Missing() + private var _region: Optional = Optional.Missing() var region: String? by ::_region.delegate() - private var _verificationLevel: Optional = Optional.Missing() + private var _verificationLevel: Optional = Optional.Missing() var verificationLevel: VerificationLevel? by ::_verificationLevel.delegate() - private var _notificationLevel: Optional = Optional.Missing() + private var _notificationLevel: Optional = Optional.Missing() var notificationLevel: DefaultMessageNotificationLevel? by ::_notificationLevel.delegate() - private var _explicitContentFilter: Optional = Optional.Missing() + private var _explicitContentFilter: Optional = Optional.Missing() var explicitContentFilter: ExplicitContentFilter? by ::_explicitContentFilter.delegate() - private var _afkChannelId: OptionalSnowflake = OptionalSnowflake.Missing + private var _afkChannelId: OptionalSnowflake? = OptionalSnowflake.Missing var afkChannelId: Snowflake? by ::_afkChannelId.delegate() private var _afkTimeout: OptionalInt = OptionalInt.Missing var afkTimeout: Int? by ::_afkTimeout.delegate() - private var _icon: Optional = Optional.Missing() + private var _icon: Optional = Optional.Missing() var icon: Image? by ::_icon.delegate() private var _ownerId: OptionalSnowflake = OptionalSnowflake.Missing var ownerId: Snowflake? by ::_ownerId.delegate() - private var _splash: Optional = Optional.Missing() + private var _splash: Optional = Optional.Missing() var splash: Image? by ::_splash.delegate() - private var _banner: Optional = Optional.Missing() + private var _banner: Optional = Optional.Missing() var banner: Image? by ::_banner.delegate() - private var _systemChannelId: OptionalSnowflake = OptionalSnowflake.Missing + private var _systemChannelId: OptionalSnowflake? = OptionalSnowflake.Missing var systemChannelId: Snowflake? by ::_systemChannelId.delegate() - private var _rulesChannelId: OptionalSnowflake = OptionalSnowflake.Missing + private var _rulesChannelId: OptionalSnowflake? = OptionalSnowflake.Missing /** * The id of the channel where "PUBLIC" guilds display rules and/or guidelines. */ var rulesChannelId: Snowflake? by ::_rulesChannelId.delegate() - private var _publicUpdatesChannelId: OptionalSnowflake = OptionalSnowflake.Missing + private var _publicUpdatesChannelId: OptionalSnowflake? = OptionalSnowflake.Missing /** * The id of the channel where admins and moderators of "PUBLIC" guilds receive notices from Discord. */ var publicUpdatesChannelId: Snowflake? by ::_publicUpdatesChannelId.delegate() - private var _preferredLocale: Optional = Optional.Missing() + private var _preferredLocale: Optional = Optional.Missing() /** * The preferred locale of a "PUBLIC" guild used in server discovery and notices from Discord; defaults to "en-US". */ diff --git a/rest/src/main/kotlin/builder/member/MemberModifyBuilder.kt b/rest/src/main/kotlin/builder/member/MemberModifyBuilder.kt index d9c49d0ce17..f1fd62a2c3b 100644 --- a/rest/src/main/kotlin/builder/member/MemberModifyBuilder.kt +++ b/rest/src/main/kotlin/builder/member/MemberModifyBuilder.kt @@ -13,25 +13,26 @@ import dev.kord.rest.json.request.GuildMemberModifyRequest class MemberModifyBuilder : AuditRequestBuilder { override var reason: String? = null - private var _voiceChannelId: OptionalSnowflake = OptionalSnowflake.Missing + private var _voiceChannelId: OptionalSnowflake? = OptionalSnowflake.Missing var voiceChannelId: Snowflake? by ::_voiceChannelId.delegate() - private var _muted: OptionalBoolean = OptionalBoolean.Missing + private var _muted: OptionalBoolean? = OptionalBoolean.Missing var muted: Boolean? by ::_muted.delegate() - private var _deafened: OptionalBoolean = OptionalBoolean.Missing + private var _deafened: OptionalBoolean? = OptionalBoolean.Missing var deafened: Boolean? by ::_deafened.delegate() - private var _nickname: Optional = Optional.Missing() + private var _nickname: Optional = Optional.Missing() var nickname: String? by ::_nickname.delegate() - var roles: MutableSet = mutableSetOf() + private var _roles: Optional?> = Optional.Missing() + var roles: MutableSet? by ::_roles.delegate() override fun toRequest(): GuildMemberModifyRequest = GuildMemberModifyRequest( nick = _nickname, channelId = _voiceChannelId, mute = _muted, deaf = _deafened, - roles = Optional.missingOnEmpty(roles) + roles = _roles ) } \ No newline at end of file diff --git a/rest/src/main/kotlin/builder/role/RoleModifyBuilder.kt b/rest/src/main/kotlin/builder/role/RoleModifyBuilder.kt index 7b977a57983..de8fecd6936 100644 --- a/rest/src/main/kotlin/builder/role/RoleModifyBuilder.kt +++ b/rest/src/main/kotlin/builder/role/RoleModifyBuilder.kt @@ -13,19 +13,19 @@ import dev.kord.rest.json.request.GuildRoleModifyRequest class RoleModifyBuilder : AuditRequestBuilder { override var reason: String? = null - private var _color: Optional = Optional.Missing() + private var _color: Optional = Optional.Missing() var color: Color? by ::_color.delegate() - private var _hoist: OptionalBoolean = OptionalBoolean.Missing + private var _hoist: OptionalBoolean? = OptionalBoolean.Missing var hoist: Boolean? by ::_hoist.delegate() - private var _name: Optional = Optional.Missing() + private var _name: Optional = Optional.Missing() var name: String? by ::_name.delegate() - private var _mentionable: OptionalBoolean = OptionalBoolean.Missing + private var _mentionable: OptionalBoolean? = OptionalBoolean.Missing var mentionable: Boolean? by ::_mentionable.delegate() - private var _permissions: Optional = Optional.Missing() + private var _permissions: Optional = Optional.Missing() var permissions: Permissions? by ::_permissions.delegate() override fun toRequest(): GuildRoleModifyRequest = GuildRoleModifyRequest( diff --git a/rest/src/main/kotlin/builder/user/CurrentUserModifyBuilder.kt b/rest/src/main/kotlin/builder/user/CurrentUserModifyBuilder.kt index 4c7aab47528..2a8c65f6f6d 100644 --- a/rest/src/main/kotlin/builder/user/CurrentUserModifyBuilder.kt +++ b/rest/src/main/kotlin/builder/user/CurrentUserModifyBuilder.kt @@ -19,7 +19,7 @@ class CurrentUserModifyBuilder : RequestBuilder { var avatar: Image? by ::_avatar.delegate() override fun toRequest(): CurrentUserModifyRequest = CurrentUserModifyRequest( - _username, _avatar.mapNullable { it?.dataUri } + _username, _avatar.map { it.dataUri } ) } \ No newline at end of file diff --git a/rest/src/main/kotlin/builder/webhook/WebhookModifyBuilder.kt b/rest/src/main/kotlin/builder/webhook/WebhookModifyBuilder.kt index 248ee2eb8d6..0a298341103 100644 --- a/rest/src/main/kotlin/builder/webhook/WebhookModifyBuilder.kt +++ b/rest/src/main/kotlin/builder/webhook/WebhookModifyBuilder.kt @@ -17,7 +17,7 @@ class WebhookModifyBuilder: AuditRequestBuilder { private var _name: Optional = Optional.Missing() var name: String? by ::_name.delegate() - private var _avatar: Optional = Optional.Missing() + private var _avatar: Optional = Optional.Missing() var avatar: Image? by ::_avatar.delegate() private var _channelId: OptionalSnowflake = OptionalSnowflake.Missing diff --git a/rest/src/main/kotlin/json/request/EmojiRequests.kt b/rest/src/main/kotlin/json/request/EmojiRequests.kt index 733a0196d68..e8a913683be 100644 --- a/rest/src/main/kotlin/json/request/EmojiRequests.kt +++ b/rest/src/main/kotlin/json/request/EmojiRequests.kt @@ -8,11 +8,11 @@ import kotlinx.serialization.Serializable data class EmojiCreateRequest( val name: String, val image: String, - val roles: Set + val roles: Iterable ) @Serializable data class EmojiModifyRequest( val name: Optional = Optional.Missing(), - val roles: Optional> = Optional.Missing() + val roles: Optional?> = Optional.Missing() ) \ No newline at end of file diff --git a/rest/src/main/kotlin/json/request/GuildRequests.kt b/rest/src/main/kotlin/json/request/GuildRequests.kt index 72e9cd22142..b00b434398c 100644 --- a/rest/src/main/kotlin/json/request/GuildRequests.kt +++ b/rest/src/main/kotlin/json/request/GuildRequests.kt @@ -56,13 +56,13 @@ data class GuildChannelCreateRequest( @Serializable data class ChannelPositionSwapRequest( val id: Snowflake, - val position: Int?, + val position: OptionalInt? = OptionalInt.Missing, @KordExperimental @SerialName("lock_permissions") - val lockPermissions: Boolean?, + val lockPermissions: Boolean? = null, @KordExperimental @SerialName("parent_id") - val parentId: Snowflake? + val parentId: Snowflake? = null ) @Serializable(with = GuildChannelPositionModifyRequest.Serializer::class) @@ -156,7 +156,7 @@ data class GuildRolePositionModifyRequest(val swaps: List>) data class GuildRoleModifyRequest( val name: Optional = Optional.Missing(), val permissions: Optional = Optional.Missing(), - val color: Optional = Optional.Missing(), + val color: Optional = Optional.Missing(), @SerialName("hoist") val separate: OptionalBoolean? = OptionalBoolean.Missing, val mentionable: OptionalBoolean? = OptionalBoolean.Missing, @@ -199,28 +199,28 @@ data class CurrentUserNicknameModifyRequest( @Serializable data class GuildModifyRequest( val name: Optional = Optional.Missing(), - val region: Optional = Optional.Missing(), + val region: Optional = Optional.Missing(), @SerialName("verification_level") - val verificationLevel: Optional = Optional.Missing(), + val verificationLevel: Optional = Optional.Missing(), @SerialName("default_message_notifications") - val defaultMessageNotificationLevel: Optional = Optional.Missing(), + val defaultMessageNotificationLevel: Optional = Optional.Missing(), @SerialName("explicit_content_filter") - val contentFilter: Optional = Optional.Missing(), + val contentFilter: Optional = Optional.Missing(), @SerialName("afk_channel_id") - val afkChannelId: OptionalSnowflake = OptionalSnowflake.Missing, + val afkChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, @SerialName("afk_timeout") val afkTimeout: OptionalInt = OptionalInt.Missing, - val icon: Optional = Optional.Missing(), + val icon: Optional = Optional.Missing(), @SerialName("owner_id") val ownerId: OptionalSnowflake = OptionalSnowflake.Missing, - val splash: Optional = Optional.Missing(), - val banner: Optional = Optional.Missing(), + val splash: Optional = Optional.Missing(), + val banner: Optional = Optional.Missing(), @SerialName("system_channel_id") - val systemChannelId: OptionalSnowflake = OptionalSnowflake.Missing, + val systemChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, @SerialName("rules_channel_id") - val rulesChannelId: OptionalSnowflake = OptionalSnowflake.Missing, + val rulesChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, @SerialName("public_updates_channel_id") - val publicUpdatesChannelId: OptionalSnowflake = OptionalSnowflake.Missing, + val publicUpdatesChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, @SerialName("preferred_locale") - val preferredLocale: Optional = Optional.Missing(), + val preferredLocale: Optional = Optional.Missing(), ) \ No newline at end of file From 105fac059e375419e13bdf4b05b27649309a75e9 Mon Sep 17 00:00:00 2001 From: HopeBaron Date: Thu, 17 Dec 2020 22:42:22 +0200 Subject: [PATCH 02/90] Allow null for channelId --- gateway/src/main/kotlin/Command.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway/src/main/kotlin/Command.kt b/gateway/src/main/kotlin/Command.kt index fed3fc5aa18..5e14ae459a0 100644 --- a/gateway/src/main/kotlin/Command.kt +++ b/gateway/src/main/kotlin/Command.kt @@ -185,7 +185,7 @@ data class UpdateVoiceStatus( @SerialName("guild_id") val guildId: Snowflake, @SerialName("channel_id") - val channelId: Snowflake, + val channelId: Snowflake?, @SerialName("self_mute") val selfMute: Boolean, @SerialName("self_deaf") From 2793788f7d649736d183168f5a8287acab7350f9 Mon Sep 17 00:00:00 2001 From: BartArys Date: Mon, 4 Jan 2021 10:27:07 +0100 Subject: [PATCH 03/90] Don't provide defaults for nullable --- rest/src/main/kotlin/json/request/GuildRequests.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rest/src/main/kotlin/json/request/GuildRequests.kt b/rest/src/main/kotlin/json/request/GuildRequests.kt index b00b434398c..f5b6cbf9827 100644 --- a/rest/src/main/kotlin/json/request/GuildRequests.kt +++ b/rest/src/main/kotlin/json/request/GuildRequests.kt @@ -59,10 +59,10 @@ data class ChannelPositionSwapRequest( val position: OptionalInt? = OptionalInt.Missing, @KordExperimental @SerialName("lock_permissions") - val lockPermissions: Boolean? = null, + val lockPermissions: Boolean?, @KordExperimental @SerialName("parent_id") - val parentId: Snowflake? = null + val parentId: Snowflake? ) @Serializable(with = GuildChannelPositionModifyRequest.Serializer::class) From a10e090ef5a951ac4219c6615053492229e8bf6a Mon Sep 17 00:00:00 2001 From: Hope <34831095+HopeBaron@users.noreply.github.com> Date: Mon, 4 Jan 2021 13:05:22 +0200 Subject: [PATCH 04/90] Add missing template endpoints (#137) * Add missing template endpoints * Document stuff Co-authored-by: HopeBaron --- .../builder/template/TemplateBuilders.kt | 25 +++++- .../kotlin/json/request/TemplateRequests.kt | 14 +++- rest/src/main/kotlin/route/Route.kt | 26 ++++-- .../main/kotlin/service/TemplateService.kt | 83 ++++++++++++++++++- 4 files changed, 136 insertions(+), 12 deletions(-) diff --git a/rest/src/main/kotlin/builder/template/TemplateBuilders.kt b/rest/src/main/kotlin/builder/template/TemplateBuilders.kt index 492220fd88e..c733a2c1b39 100644 --- a/rest/src/main/kotlin/builder/template/TemplateBuilders.kt +++ b/rest/src/main/kotlin/builder/template/TemplateBuilders.kt @@ -5,15 +5,36 @@ import dev.kord.common.entity.optional.delegate.delegate import dev.kord.common.entity.optional.map import dev.kord.rest.Image import dev.kord.rest.builder.RequestBuilder +import dev.kord.rest.json.request.GuildFromTemplateCreateRequest import dev.kord.rest.json.request.GuildTemplateCreateRequest +import dev.kord.rest.json.request.GuildTemplateModifyRequest -class GuildFromTemplateCreateBuilder(var name: String) : RequestBuilder { +class GuildFromTemplateCreateBuilder(var name: String) : RequestBuilder { private var _image: Optional = Optional.Missing() var image: Image? by ::_image.delegate() - override fun toRequest(): GuildTemplateCreateRequest = GuildTemplateCreateRequest( + override fun toRequest(): GuildFromTemplateCreateRequest = GuildFromTemplateCreateRequest( name, _image.map { it.dataUri } ) +} + +class GuildTemplateCreateBuilder(var name: String) : RequestBuilder { + private var _description: Optional = Optional.Missing() + var description: String? by ::_description.delegate() + + override fun toRequest(): GuildTemplateCreateRequest = GuildTemplateCreateRequest(name, _description) +} + + +class GuildTemplateModifyBuilder : RequestBuilder { + + private var _name: Optional = Optional.Missing() + var name: String? by ::_name.delegate() + + private var _description: Optional = Optional.Missing() + var description: String? by ::_description.delegate() + + override fun toRequest(): GuildTemplateModifyRequest = GuildTemplateModifyRequest(_name, _description) } \ No newline at end of file diff --git a/rest/src/main/kotlin/json/request/TemplateRequests.kt b/rest/src/main/kotlin/json/request/TemplateRequests.kt index 53426006f4d..87ba71a7474 100644 --- a/rest/src/main/kotlin/json/request/TemplateRequests.kt +++ b/rest/src/main/kotlin/json/request/TemplateRequests.kt @@ -4,7 +4,19 @@ import dev.kord.common.entity.optional.Optional import kotlinx.serialization.Serializable @Serializable -data class GuildTemplateCreateRequest( +data class GuildFromTemplateCreateRequest( val name: String, val image: Optional = Optional.Missing() +) + +@Serializable +data class GuildTemplateModifyRequest( + val name: Optional = Optional.Missing(), + val description: Optional = Optional.Missing() +) + +@Serializable +data class GuildTemplateCreateRequest( + val name: String, + val description: Optional = Optional.Missing() ) \ No newline at end of file diff --git a/rest/src/main/kotlin/route/Route.kt b/rest/src/main/kotlin/route/Route.kt index 748e1a02f74..c6f4ec4252a 100644 --- a/rest/src/main/kotlin/route/Route.kt +++ b/rest/src/main/kotlin/route/Route.kt @@ -6,10 +6,11 @@ import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.* import dev.kord.rest.json.optional import dev.kord.rest.json.response.* -import io.ktor.http.HttpMethod -import kotlinx.serialization.* +import io.ktor.http.* +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.InternalSerializationApi import kotlinx.serialization.builtins.ListSerializer -import kotlinx.serialization.builtins.serializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.StructureKind import kotlinx.serialization.descriptors.buildSerialDescriptor @@ -343,9 +344,24 @@ sealed class Route( object TemplateGet : Route(HttpMethod.Get, "guilds/templates/${TemplateCode}", DiscordTemplate.serializer()) - object TemplatePost + object GuildFromTemplatePost : Route(HttpMethod.Post, "guilds/templates/${TemplateCode}", DiscordGuild.serializer()) + object GuildTemplatesGet + : Route>(HttpMethod.Get, "/guilds/${GuildId}/templates", ListSerializer(DiscordTemplate.serializer())) + + object GuildTemplatePost + : Route(HttpMethod.Post, "/guilds/${GuildId}/templates", DiscordTemplate.serializer()) + + object TemplateSyncPut + : Route(HttpMethod.Put, "/guilds/${GuildId}/templates/${TemplateCode}", DiscordTemplate.serializer()) + + object TemplatePatch + : Route(HttpMethod.Patch, "/guilds/${GuildId}/templates/${TemplateCode}", DiscordTemplate.serializer()) + + object TemplateDelete + : Route(HttpMethod.Delete, "/guilds/${GuildId}/templates/${TemplateCode}", DiscordTemplate.serializer()) + companion object { val baseUrl = "https://discord.com/api/$restVersion" } @@ -366,7 +382,7 @@ sealed class Route( object IntegrationId : Key("{integration.id}") object WebhookId : Key("{webhook.id}", true) object WebhookToken : Key("{webhook.token}") - object TemplateCode: Key("{template.code}") + object TemplateCode : Key("{template.code}") } diff --git a/rest/src/main/kotlin/service/TemplateService.kt b/rest/src/main/kotlin/service/TemplateService.kt index 8eb7f935b2c..9713e93b5d3 100644 --- a/rest/src/main/kotlin/service/TemplateService.kt +++ b/rest/src/main/kotlin/service/TemplateService.kt @@ -2,8 +2,13 @@ package dev.kord.rest.service import dev.kord.common.entity.DiscordGuild import dev.kord.common.entity.DiscordTemplate +import dev.kord.common.entity.Snowflake import dev.kord.rest.builder.template.GuildFromTemplateCreateBuilder +import dev.kord.rest.builder.template.GuildTemplateCreateBuilder +import dev.kord.rest.builder.template.GuildTemplateModifyBuilder +import dev.kord.rest.json.request.GuildFromTemplateCreateRequest import dev.kord.rest.json.request.GuildTemplateCreateRequest +import dev.kord.rest.json.request.GuildTemplateModifyRequest import dev.kord.rest.request.RequestHandler import dev.kord.rest.route.Route @@ -12,24 +17,94 @@ class TemplateService(requestHandler: RequestHandler) : RestService(requestHandl /** * Returns a [DiscordTemplate] from the given code. */ - suspend fun getTemplate(code: String): DiscordTemplate = call(Route.TemplateGet){ + suspend fun getGuildTemplate(code: String): DiscordTemplate = call(Route.TemplateGet) { keys[Route.TemplateCode] = code } /** * Create a new guild based on a template with the given [code] and configured by the [request], returns the created guild. */ - suspend fun createGuildTemplate(code: String, request: GuildTemplateCreateRequest): DiscordGuild = call(Route.TemplatePost){ + suspend fun createGuildFromTemplate(code: String, request: GuildFromTemplateCreateRequest): DiscordGuild = call(Route.GuildFromTemplatePost) { keys[Route.TemplateCode] = code + body(GuildFromTemplateCreateRequest.serializer(), request) + } + + /** + * Creates a template given [guildId] configured by [request] + * + * Returns created [DiscordTemplate]. + */ + suspend fun createGuildTemplate(guildId: Snowflake, request: GuildTemplateCreateRequest) = call(Route.GuildTemplatePost) { + keys[Route.GuildId] = guildId body(GuildTemplateCreateRequest.serializer(), request) } + /** + * Returns a list of [DiscordTemplate] given [guildId]. + */ + suspend fun getGuildTemplates(guildId: Snowflake) = call(Route.GuildTemplatesGet) { + keys[Route.GuildId] = guildId + } + + /** + * Synchronizes a template with [code] with the current state of the Guild with [guildId] + * + * Returns synchronized [DiscordTemplate]. + */ + suspend fun syncGuildTemplate(guildId: Snowflake, code: String) = call(Route.TemplateSyncPut) { + keys[Route.GuildId] = guildId + keys[Route.TemplateCode] = code + } + + /** + * Deletes a template given [code] and [guildId]. + * + * Returns deleted [DiscordTemplate] + */ + suspend fun deleteGuildTemplate(guildId: Snowflake, code: String) = call(Route.TemplateDelete) { + keys[Route.GuildId] = guildId + keys[Route.TemplateCode] = code + } + + /** + * Modifies existing guild template configured by [request] given [code] and [guildId]. + * + * Returns the modified [DiscordTemplate]. + */ + + suspend fun modifyGuildTemplate(guildId: Snowflake, code: String, request: GuildTemplateModifyRequest) = call(Route.TemplatePatch) { + keys[Route.GuildId] = guildId + keys[Route.TemplateCode] = code + body(GuildTemplateModifyRequest.serializer(), request) + } + + /** * Create a new guild with a [name] based on a template with the given [code] and configured by the [builder], returns the created guild. */ - suspend inline fun createGuildTemplate(code: String, name: String, builder: GuildFromTemplateCreateBuilder.() -> Unit): DiscordGuild { + suspend inline fun createGuildFromTemplate(code: String, name: String, builder: GuildFromTemplateCreateBuilder.() -> Unit): DiscordGuild { val request = GuildFromTemplateCreateBuilder(name).apply(builder).toRequest() - return createGuildTemplate(code, request) + return createGuildFromTemplate(code, request) + } + + /** + * Modifies existing guild template configured by [builder] given [code] and [guildId]. + * + * Returns the modified [DiscordTemplate]. + */ + suspend inline fun modifyGuildTemplate(guildId: Snowflake, code: String, builder: GuildTemplateModifyBuilder.() -> Unit): DiscordTemplate { + val request = GuildTemplateModifyBuilder().apply(builder).toRequest() + return modifyGuildTemplate(guildId, code, request) + } + + /** + * Creates a guild template with [name] inside the guild with [guildId] configured by [builder]. + * + * Returns the new [DiscordTemplate]. + */ + suspend inline fun createGuildTemplate(guildId: Snowflake, name: String, builder: GuildTemplateCreateBuilder.() -> Unit): DiscordTemplate { + val request = GuildTemplateCreateBuilder(name).apply(builder).toRequest() + return createGuildTemplate(guildId, request) } } \ No newline at end of file From c4978a8f0125d8fcc211734e0cd1c92b3dcb1453 Mon Sep 17 00:00:00 2001 From: Hope <34831095+HopeBaron@users.noreply.github.com> Date: Mon, 4 Jan 2021 14:09:40 +0200 Subject: [PATCH 05/90] Add template core representation (#138) * Add missing template endpoints * Document stuff * Add template core representation --- CHANGELOG.md | 10 ++ .../src/main/kotlin/entity/DiscordTemplate.kt | 2 +- .../src/main/kotlin/behavior/GuildBehavior.kt | 135 ++++++++++++------ .../main/kotlin/behavior/TemplateBehavior.kt | 59 ++++++++ .../main/kotlin/cache/data/TemplateData.kt | 43 ++++++ core/src/main/kotlin/entity/Template.kt | 35 +++++ .../exception/EntityNotFoundException.kt | 3 + .../kotlin/supplier/CacheEntitySupplier.kt | 32 +++-- .../main/kotlin/supplier/EntitySupplier.kt | 46 ++++-- .../kotlin/supplier/FallbackEntitySupplier.kt | 8 ++ .../kotlin/supplier/RestEntitySupplier.kt | 75 ++++++---- .../builder/template/TemplateBuilders.kt | 2 +- rest/src/main/kotlin/service/RestClient.kt | 1 + 13 files changed, 357 insertions(+), 94 deletions(-) create mode 100644 core/src/main/kotlin/behavior/TemplateBehavior.kt create mode 100644 core/src/main/kotlin/cache/data/TemplateData.kt create mode 100644 core/src/main/kotlin/entity/Template.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a788045c42..51d53fd04d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# 0.7.x + +## Additions + +* Added core representation of templates #136 + +## Fixes + +* Fix `GuildBehavior#getWidgetOrNull` + # 0.7.0-RC ## Additions diff --git a/common/src/main/kotlin/entity/DiscordTemplate.kt b/common/src/main/kotlin/entity/DiscordTemplate.kt index 9a9672367b7..b57a7bc309d 100644 --- a/common/src/main/kotlin/entity/DiscordTemplate.kt +++ b/common/src/main/kotlin/entity/DiscordTemplate.kt @@ -20,7 +20,7 @@ data class DiscordTemplate( @SerialName("source_guild_id") val sourceGuildId: Snowflake, @SerialName("serialized_source_guild") - val serializedSourceGuild: DiscordGuild, + val serializedSourceGuild: DiscordPartialGuild, @SerialName("is_dirty") val isDirty: Boolean? ) \ No newline at end of file diff --git a/core/src/main/kotlin/behavior/GuildBehavior.kt b/core/src/main/kotlin/behavior/GuildBehavior.kt index daef896a69b..ecf70d6d392 100644 --- a/core/src/main/kotlin/behavior/GuildBehavior.kt +++ b/core/src/main/kotlin/behavior/GuildBehavior.kt @@ -45,7 +45,6 @@ import java.util.* import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract -import kotlin.random.Random /** * The behavior of a [Discord Guild](https://discord.com/developers/docs/resources/guild). @@ -105,8 +104,8 @@ interface GuildBehavior : Entity, Strategizable { */ val presences: Flow get() = kord.cache.query { idEq(PresenceData::guildId, id) } - .asFlow() - .map { Presence(it, kord) } + .asFlow() + .map { Presence(it, kord) } /** * Requests to get all present members in this guild. @@ -153,9 +152,9 @@ interface GuildBehavior : Entity, Strategizable { */ val voiceStates: Flow get() = kord.cache - .query { idEq(VoiceStateData::guildId, id) } - .asFlow() - .map { VoiceState(it, kord) } + .query { idEq(VoiceStateData::guildId, id) } + .asFlow() + .map { VoiceState(it, kord) } /** * Requests to get the present voice states of this guild. @@ -172,6 +171,9 @@ interface GuildBehavior : Entity, Strategizable { } } + val templates: Flow