Skip to content

Commit

Permalink
Add Role tags
Browse files Browse the repository at this point in the history
  • Loading branch information
BartArys committed Nov 27, 2020
1 parent 78a9519 commit 75bc038
Show file tree
Hide file tree
Showing 8 changed files with 176 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.gitlab.kordlib.common.entity

import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

/**
* Type to represent a Discord value that can only be null. This class cannot be instantiated.
*/
@Serializable(with = DiscordNull.Serializer::class)
class DiscordNull private constructor() {

internal object Serializer : KSerializer<DiscordNull> {

override val descriptor: SerialDescriptor
get() = buildClassSerialDescriptor("Kord.DiscordNull")

override fun deserialize(decoder: Decoder): DiscordNull {
throw SerializationException("DiscordNull cannot have an instance.")
}

override fun serialize(encoder: Encoder, value: DiscordNull) {
throw SerializationException("DiscordNull cannot be encoded.")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ package com.gitlab.kordlib.common.entity
import com.gitlab.kordlib.common.entity.optional.Optional
import com.gitlab.kordlib.common.entity.optional.OptionalBoolean
import com.gitlab.kordlib.common.entity.optional.OptionalInt
import com.gitlab.kordlib.common.entity.optional.OptionalSnowflake
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

@Serializable
data class DiscordRole(
Expand All @@ -15,7 +22,17 @@ data class DiscordRole(
val position: Int,
val permissions: Permissions,
val managed: Boolean,
val mentionable: Boolean
val mentionable: Boolean,
val tags: Optional<DiscordRoleTags> = Optional.Missing(),
)

@Serializable
data class DiscordRoleTags(
val botId: OptionalSnowflake = OptionalSnowflake.Missing,
@SerialName("integration_id")
val integrationId: OptionalSnowflake = OptionalSnowflake.Missing,
@SerialName("premium_subscriber")
val premiumSubscriber: Optional<DiscordNull?> = Optional.Missing(),
)

@Serializable
Expand All @@ -27,10 +44,10 @@ data class DiscordPartialRole(
val position: OptionalInt = OptionalInt.Missing,
val permissions: Optional<Permissions> = Optional.Missing(),
val managed: OptionalBoolean = OptionalBoolean.Missing,
val mentionable: OptionalBoolean = OptionalBoolean.Missing
val mentionable: OptionalBoolean = OptionalBoolean.Missing,
val tags: Optional<DiscordRoleTags> = Optional.Missing(),
)


@Serializable
data class DiscordAuditLogRoleChange(
val id: String,
Expand All @@ -40,20 +57,20 @@ data class DiscordAuditLogRoleChange(
val position: Int? = null,
val permissions: Permissions? = null,
val managed: Boolean? = null,
val mentionable: Boolean? = null
val mentionable: Boolean? = null,
)

@Serializable
data class DiscordGuildRole(
@SerialName("guild_id")
val guildId: Snowflake,
val role: DiscordRole
val role: DiscordRole,
)

@Serializable
data class DiscordDeletedGuildRole(
@SerialName("guild_id")
val guildId: Snowflake,
@SerialName("role_id")
val id: Snowflake
val id: Snowflake,
)
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ inline fun <E : Any> Optional<E?>.mapSnowflake(mapper: (E) -> Snowflake): Option
is Value -> OptionalSnowflake.Value(mapper(value!!))
}

inline fun <T, R: Any> Optional<T>.unwrap(mapper: (T) -> R) : R? = when(this){
is Missing, is Null<*> -> null
is Value -> mapper(value)
}

@Suppress("UNCHECKED_CAST")
fun <T : Any> Optional<T?>.coerceToMissing(): Optional<T> = when (this) {
is Missing, is Null -> Missing()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ data class MessageStickerData(
val packId: Snowflake,
val name: String,
val description: String,
val tags: Optional<String>,
val tags: Optional<String> = Optional.Missing(),
val asset: String,
val previewAsset: String?,
val formatType: MessageStickerType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import com.gitlab.kordlib.common.entity.DiscordGuildRole
import com.gitlab.kordlib.common.entity.DiscordRole
import com.gitlab.kordlib.common.entity.Permissions
import com.gitlab.kordlib.common.entity.Snowflake
import com.gitlab.kordlib.common.entity.optional.Optional
import com.gitlab.kordlib.common.entity.optional.map
import kotlinx.serialization.Serializable

@Serializable
Expand All @@ -17,13 +19,14 @@ data class RoleData(
val position: Int,
val permissions: Permissions,
val managed: Boolean,
val mentionable: Boolean
val mentionable: Boolean,
val tags: Optional<RoleTagsData> = Optional.Missing()
) {
companion object {
val description = description(RoleData::id)

fun from(guildId: Snowflake, entity: DiscordRole) = with(entity) {
RoleData(id, guildId, name, color, hoist, position, permissions, managed, mentionable)
RoleData(id, guildId, name, color, hoist, position, permissions, managed, mentionable, tags.map { RoleTagsData.from(it) })
}

fun from(entity: DiscordGuildRole) = from(entity.guildId, entity.role)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.gitlab.kordlib.core.cache.data

import com.gitlab.kordlib.common.entity.DiscordRoleTags
import com.gitlab.kordlib.common.entity.optional.Optional
import com.gitlab.kordlib.common.entity.optional.OptionalSnowflake
import kotlinx.serialization.Serializable

@Serializable
data class RoleTagsData(
val botId: OptionalSnowflake,
val integrationId: OptionalSnowflake,
val premiumSubscriber: Boolean,
) {

companion object {
fun from(entity: DiscordRoleTags): RoleTagsData = with(entity) {
RoleTagsData(botId, integrationId, premiumSubscriber is Optional.Null)
}
}

}
6 changes: 6 additions & 0 deletions core/src/main/kotlin/com/gitlab/kordlib/core/entity/Role.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.gitlab.kordlib.core.entity
import com.gitlab.kordlib.common.Color
import com.gitlab.kordlib.common.entity.Permissions
import com.gitlab.kordlib.common.entity.Snowflake
import com.gitlab.kordlib.common.entity.optional.unwrap
import com.gitlab.kordlib.core.Kord
import com.gitlab.kordlib.core.behavior.RoleBehavior
import com.gitlab.kordlib.core.cache.data.RoleData
Expand Down Expand Up @@ -36,6 +37,11 @@ data class Role(

val rawPosition: Int get() = data.position

/**
* The tags of this role, if present.
*/
val tags: RoleTags? get() = data.tags.unwrap { RoleTags(it, guildId, kord) }

override fun compareTo(other: Entity): Int = when (other) {
is Role -> compareBy<Role> { it.rawPosition }.thenBy { it.guildId }.compare(this, other)
else -> super.compareTo(other)
Expand Down
85 changes: 85 additions & 0 deletions core/src/main/kotlin/com/gitlab/kordlib/core/entity/RoleTags.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.gitlab.kordlib.core.entity

import com.gitlab.kordlib.common.entity.Snowflake
import com.gitlab.kordlib.core.Kord
import com.gitlab.kordlib.core.KordObject
import com.gitlab.kordlib.core.behavior.GuildBehavior
import com.gitlab.kordlib.core.cache.data.IntegrationData
import com.gitlab.kordlib.core.cache.data.RoleTagsData
import com.gitlab.kordlib.core.supplier.EntitySupplier
import com.gitlab.kordlib.common.exception.RequestException
import com.gitlab.kordlib.core.exception.EntityNotFoundException
import com.gitlab.kordlib.core.supplier.EntitySupplyStrategy

class RoleTags(
val data: RoleTagsData,
val guildId: Snowflake,
override val kord: Kord,
override val supplier: EntitySupplier = kord.defaultSupplier,
) : KordObject, Strategizable {

/**
* The ID of the bot this belongs to.
*/
val botId: Snowflake? get() = data.botId.value

/**
* The ID of the of the [Integration] this role belongs to.
*/
val integrationId: Snowflake? get() = data.integrationId.value

/**
* Whether this is the guild's premium subscriber role.
*/
val isPremiumRole: Boolean get() = data.premiumSubscriber

/**
* The guild behavior this tag belongs to.
*/
val guild: GuildBehavior get() = GuildBehavior(guildId, kord)

/**
* Requests to get the bot of this tag through the [supplier],
* returns null if the [Member] isn't present.
*
* @throws [RequestException] if anything went wrong during the request.
*/
suspend fun getBot(): Member? {
val id = botId ?: return null
return supplier.getMemberOrNull(guildId, id)
}

/**
* Requests to get the integration of this tag through the [supplier],
* returns null if the [Integration] isn't present.
*
* @throws [RequestException] if anything went wrong during the request.
*/
suspend fun getIntegration(): Integration? {
val id = integrationId ?: return null
val response = kord.rest.guild.getGuildIntegrations(guildId)
.firstOrNull { it.id == id } ?: return null

return Integration(IntegrationData.from(guildId, response), kord)
}

/**
* Requests to get the guild of this tag through the [supplier].
*
* @throws [RequestException] if anything went wrong during the request.
* @throws [EntityNotFoundException] if the [Guild] wasn't present.
*/
suspend fun getGuild(): Guild = supplier.getGuild(guildId)

/**
* Requests to get the guild of this tag through the [supplier],
* returns null if the [Guild] isn't present.
*
* @throws [RequestException] if anything went wrong during the request.
*/
suspend fun getGuildOrNull(): Guild? = supplier.getGuildOrNull(guildId)

override fun withStrategy(strategy: EntitySupplyStrategy<*>): Strategizable =
RoleTags(data, guildId, kord, strategy.supply(kord))

}

0 comments on commit 75bc038

Please sign in to comment.