From 7c18bd10e8664879d1f89219aaba70d258a13fc6 Mon Sep 17 00:00:00 2001 From: lukellmann <47486203+lukellmann@users.noreply.github.com> Date: Sun, 3 Sep 2023 02:50:49 +0200 Subject: [PATCH] Add RoleFlags (#866) See https://github.com/discord/discord-api-docs/pull/6269 --- common/api/common.api | 76 ++++- .../kotlin/dev/kord/common/entity/RoleFlag.kt | 316 ++++++++++++++++++ .../commonMain/kotlin/entity/DiscordRole.kt | 12 + .../commonTest/kotlin/json/PermissionsTest.kt | 1 + core/api/core.api | 13 +- .../commonMain/kotlin/cache/data/RoleData.kt | 12 +- core/src/commonMain/kotlin/entity/Role.kt | 4 + .../commonTest/kotlin/live/LiveGuildTest.kt | 6 +- .../commonTest/kotlin/live/LiveRoleTest.kt | 6 +- .../generation/bitflags/Documentation.kt | 13 +- 10 files changed, 434 insertions(+), 25 deletions(-) create mode 100644 common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/RoleFlag.kt diff --git a/common/api/common.api b/common/api/common.api index cb426e30c5e..01642caab40 100644 --- a/common/api/common.api +++ b/common/api/common.api @@ -5517,12 +5517,13 @@ public final class dev/kord/common/entity/DiscordRemovedGuildMember$Companion { public final class dev/kord/common/entity/DiscordRole { public static final field Companion Ldev/kord/common/entity/DiscordRole$Companion; - public synthetic fun (ILdev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;)V - public synthetic fun (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (ILdev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/RoleFlags;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V + public fun (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/RoleFlags;)V + public synthetic fun (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/RoleFlags;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ldev/kord/common/entity/Snowflake; public final fun component10 ()Z public final fun component11 ()Ldev/kord/common/entity/optional/Optional; + public final fun component12 ()Ldev/kord/common/entity/RoleFlags; public final fun component2 ()Ljava/lang/String; public final fun component3 ()I public final fun component4 ()Z @@ -5531,10 +5532,11 @@ public final class dev/kord/common/entity/DiscordRole { public final fun component7 ()I public final fun component8 ()Ldev/kord/common/entity/Permissions; public final fun component9 ()Z - public final fun copy (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;)Ldev/kord/common/entity/DiscordRole; - public static synthetic fun copy$default (Ldev/kord/common/entity/DiscordRole;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;ILjava/lang/Object;)Ldev/kord/common/entity/DiscordRole; + public final fun copy (Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/RoleFlags;)Ldev/kord/common/entity/DiscordRole; + public static synthetic fun copy$default (Ldev/kord/common/entity/DiscordRole;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/RoleFlags;ILjava/lang/Object;)Ldev/kord/common/entity/DiscordRole; public fun equals (Ljava/lang/Object;)Z public final fun getColor ()I + public final fun getFlags ()Ldev/kord/common/entity/RoleFlags; public final fun getHoist ()Z public final fun getIcon ()Ldev/kord/common/entity/optional/Optional; public final fun getId ()Ldev/kord/common/entity/Snowflake; @@ -8307,6 +8309,70 @@ public final class dev/kord/common/entity/ResolvedObjects$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public abstract class dev/kord/common/entity/RoleFlag { + public static final field Companion Ldev/kord/common/entity/RoleFlag$Companion; + public synthetic fun (ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun equals (Ljava/lang/Object;)Z + public final fun getShift ()I + public final fun getValue ()I + public final fun hashCode ()I + public final fun plus (Ldev/kord/common/entity/RoleFlag;)Ldev/kord/common/entity/RoleFlags; + public final fun plus (Ldev/kord/common/entity/RoleFlags;)Ldev/kord/common/entity/RoleFlags; + public final fun toString ()Ljava/lang/String; +} + +public final class dev/kord/common/entity/RoleFlag$Companion { + public final fun fromShift (I)Ldev/kord/common/entity/RoleFlag; + public final fun getEntries ()Ljava/util/List; +} + +public final class dev/kord/common/entity/RoleFlag$InPrompt : dev/kord/common/entity/RoleFlag { + public static final field INSTANCE Ldev/kord/common/entity/RoleFlag$InPrompt; +} + +public final class dev/kord/common/entity/RoleFlag$Unknown : dev/kord/common/entity/RoleFlag { +} + +public final class dev/kord/common/entity/RoleFlagKt { + public static final fun RoleFlags (Ljava/lang/Iterable;)Ldev/kord/common/entity/RoleFlags; + public static final fun RoleFlags (Lkotlin/jvm/functions/Function1;)Ldev/kord/common/entity/RoleFlags; + public static final fun RoleFlags ([Ldev/kord/common/entity/RoleFlag;)Ldev/kord/common/entity/RoleFlags; + public static final fun RoleFlags ([Ldev/kord/common/entity/RoleFlags;)Ldev/kord/common/entity/RoleFlags; + public static synthetic fun RoleFlags$default (Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Ldev/kord/common/entity/RoleFlags; + public static final fun RoleFlags0 (Ljava/lang/Iterable;)Ldev/kord/common/entity/RoleFlags; +} + +public final class dev/kord/common/entity/RoleFlags { + public static final field Companion Ldev/kord/common/entity/RoleFlags$Companion; + public final fun contains (Ldev/kord/common/entity/RoleFlag;)Z + public final fun contains (Ldev/kord/common/entity/RoleFlags;)Z + public final fun copy (Lkotlin/jvm/functions/Function1;)Ldev/kord/common/entity/RoleFlags; + public fun equals (Ljava/lang/Object;)Z + public final fun getValue ()I + public final fun getValues ()Ljava/util/Set; + public fun hashCode ()I + public final fun minus (Ldev/kord/common/entity/RoleFlag;)Ldev/kord/common/entity/RoleFlags; + public final fun minus (Ldev/kord/common/entity/RoleFlags;)Ldev/kord/common/entity/RoleFlags; + public final fun plus (Ldev/kord/common/entity/RoleFlag;)Ldev/kord/common/entity/RoleFlags; + public final fun plus (Ldev/kord/common/entity/RoleFlags;)Ldev/kord/common/entity/RoleFlags; + public fun toString ()Ljava/lang/String; +} + +public final class dev/kord/common/entity/RoleFlags$Builder { + public fun ()V + public fun (I)V + public synthetic fun (IILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun build ()Ldev/kord/common/entity/RoleFlags; + public final fun unaryMinus (Ldev/kord/common/entity/RoleFlag;)V + public final fun unaryMinus (Ldev/kord/common/entity/RoleFlags;)V + public final fun unaryPlus (Ldev/kord/common/entity/RoleFlag;)V + public final fun unaryPlus (Ldev/kord/common/entity/RoleFlags;)V +} + +public final class dev/kord/common/entity/RoleFlags$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + public final class dev/kord/common/entity/RoleSubscription { public static final field Companion Ldev/kord/common/entity/RoleSubscription$Companion; public synthetic fun (ILdev/kord/common/entity/Snowflake;Ljava/lang/String;IZLkotlinx/serialization/internal/SerializationConstructorMarker;)V diff --git a/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/RoleFlag.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/RoleFlag.kt new file mode 100644 index 00000000000..12f52d0d7d8 --- /dev/null +++ b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/RoleFlag.kt @@ -0,0 +1,316 @@ +// THIS FILE IS AUTO-GENERATED, DO NOT EDIT! +@file:Suppress(names = arrayOf("IncorrectFormatting", "ReplaceArrayOfWithLiteral", + "SpellCheckingInspection", "GrazieInspection")) + +package dev.kord.common.entity + +import kotlin.LazyThreadSafetyMode.PUBLICATION +import kotlin.contracts.InvocationKind.EXACTLY_ONCE +import kotlin.contracts.contract +import kotlin.jvm.JvmName +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +/** + * See [RoleFlag]s in the + * [Discord Developer Documentation](https://discord.com/developers/docs/topics/permissions#role-object-role-flags). + */ +public sealed class RoleFlag( + /** + * The position of the bit that is set in this [RoleFlag]. This is always in 0..30. + */ + public val shift: Int, +) { + init { + require(shift in 0..30) { """shift has to be in 0..30 but was $shift""" } + } + + /** + * The raw value used by Discord. + */ + public val `value`: Int + get() = 1 shl shift + + /** + * Returns an instance of [RoleFlags] that has all bits set that are set in `this` and [flag]. + */ + public operator fun plus(flag: RoleFlag): RoleFlags = RoleFlags(this.value or flag.value) + + /** + * Returns an instance of [RoleFlags] that has all bits set that are set in `this` and [flags]. + */ + public operator fun plus(flags: RoleFlags): RoleFlags = RoleFlags(this.value or flags.value) + + final override fun equals(other: Any?): Boolean = this === other || + (other is RoleFlag && this.shift == other.shift) + + final override fun hashCode(): Int = shift.hashCode() + + final override fun toString(): String = if (this is Unknown) "RoleFlag.Unknown(shift=$shift)" + else "RoleFlag.${this::class.simpleName}" + + /** + * An unknown [RoleFlag]. + * + * This is used as a fallback for [RoleFlag]s that haven't been added to Kord yet. + */ + public class Unknown internal constructor( + shift: Int, + ) : RoleFlag(shift) + + /** + * Role can be selected by members in an onboarding prompt. + */ + public object InPrompt : RoleFlag(0) + + public companion object { + /** + * A [List] of all known [RoleFlag]s. + */ + public val entries: List by lazy(mode = PUBLICATION) { + listOf( + InPrompt, + ) + } + + + /** + * Returns an instance of [RoleFlag] with [RoleFlag.shift] equal to the specified [shift]. + * + * @throws IllegalArgumentException if [shift] is not in 0..30. + */ + public fun fromShift(shift: Int): RoleFlag = when (shift) { + 0 -> InPrompt + else -> Unknown(shift) + } + } +} + +/** + * A collection of multiple [RoleFlag]s. + * + * ## Creating an instance of [RoleFlags] + * + * You can create an instance of [RoleFlags] using the following methods: + * ```kotlin + * // from individual RoleFlags + * val roleFlags1 = RoleFlags(RoleFlag.InPrompt, RoleFlag.fromShift(22)) + * + * // from an Iterable + * val iterable: Iterable = TODO() + * val roleFlags2 = RoleFlags(iterable) + * + * // using a builder + * val roleFlags3 = RoleFlags { + * +roleFlags2 + * +RoleFlag.InPrompt + * -RoleFlag.fromShift(22) + * } + * ``` + * + * ## Modifying an existing instance of [RoleFlags] + * + * You can create a modified copy of an existing instance of [RoleFlags] using the [copy] method: + * ```kotlin + * roleFlags.copy { + * +RoleFlag.InPrompt + * } + * ``` + * + * ## Mathematical operators + * + * All [RoleFlags] objects can use `+`/`-` operators: + * ```kotlin + * val roleFlags1 = roleFlags + RoleFlag.InPrompt + * val roleFlags2 = roleFlags - RoleFlag.fromShift(22) + * val roleFlags3 = roleFlags1 + roleFlags2 + * ``` + * + * ## Checking for [RoleFlag]s + * + * You can use the [contains] operator to check whether an instance of [RoleFlags] contains specific + * [RoleFlag]s: + * ```kotlin + * val hasRoleFlag = RoleFlag.InPrompt in roleFlags + * val hasRoleFlags = RoleFlags(RoleFlag.InPrompt, RoleFlag.fromShift(22)) in roleFlags + * ``` + * + * ## Unknown [RoleFlag]s + * + * Whenever [RoleFlag]s haven't been added to Kord yet, they will be deserialized as instances of + * [RoleFlag.Unknown]. + * + * You can also use [RoleFlag.fromShift] to check for [unknown][RoleFlag.Unknown] [RoleFlag]s. + * ```kotlin + * val hasUnknownRoleFlag = RoleFlag.fromShift(23) in roleFlags + * ``` + * + * @see RoleFlag + * @see RoleFlags.Builder + */ +@Serializable(with = RoleFlags.Serializer::class) +public class RoleFlags internal constructor( + /** + * The raw value used by Discord. + */ + public val `value`: Int, +) { + /** + * A [Set] of all [RoleFlag]s contained in this instance of [RoleFlags]. + */ + public val values: Set + get() = buildSet { + var remaining = value + var shift = 0 + while (remaining != 0) { + if ((remaining and 1) != 0) add(RoleFlag.fromShift(shift)) + remaining = remaining ushr 1 + shift++ + } + } + + /** + * Checks if this instance of [RoleFlags] has all bits set that are set in [flag]. + */ + public operator fun contains(flag: RoleFlag): Boolean = this.value and flag.value == flag.value + + /** + * Checks if this instance of [RoleFlags] has all bits set that are set in [flags]. + */ + public operator fun contains(flags: RoleFlags): Boolean = + this.value and flags.value == flags.value + + /** + * Returns an instance of [RoleFlags] that has all bits set that are set in `this` and [flag]. + */ + public operator fun plus(flag: RoleFlag): RoleFlags = RoleFlags(this.value or flag.value) + + /** + * Returns an instance of [RoleFlags] that has all bits set that are set in `this` and [flags]. + */ + public operator fun plus(flags: RoleFlags): RoleFlags = RoleFlags(this.value or flags.value) + + /** + * Returns an instance of [RoleFlags] that has all bits set that are set in `this` except the + * bits that are set in [flag]. + */ + public operator fun minus(flag: RoleFlag): RoleFlags = + RoleFlags(this.value and flag.value.inv()) + + /** + * Returns an instance of [RoleFlags] that has all bits set that are set in `this` except the + * bits that are set in [flags]. + */ + public operator fun minus(flags: RoleFlags): RoleFlags = + RoleFlags(this.value and flags.value.inv()) + + /** + * Returns a copy of this instance of [RoleFlags] modified with [builder]. + */ + public inline fun copy(builder: Builder.() -> Unit): RoleFlags { + contract { callsInPlace(builder, EXACTLY_ONCE) } + return Builder(value).apply(builder).build() + } + + override fun equals(other: Any?): Boolean = this === other || + (other is RoleFlags && this.value == other.value) + + override fun hashCode(): Int = value.hashCode() + + override fun toString(): String = "RoleFlags(values=$values)" + + public class Builder( + private var `value`: Int = 0, + ) { + /** + * Sets all bits in the [Builder] that are set in this [RoleFlag]. + */ + public operator fun RoleFlag.unaryPlus() { + this@Builder.value = this@Builder.value or this.value + } + + /** + * Sets all bits in the [Builder] that are set in this [RoleFlags]. + */ + public operator fun RoleFlags.unaryPlus() { + this@Builder.value = this@Builder.value or this.value + } + + /** + * Unsets all bits in the [Builder] that are set in this [RoleFlag]. + */ + public operator fun RoleFlag.unaryMinus() { + this@Builder.value = this@Builder.value and this.value.inv() + } + + /** + * Unsets all bits in the [Builder] that are set in this [RoleFlags]. + */ + public operator fun RoleFlags.unaryMinus() { + this@Builder.value = this@Builder.value and this.value.inv() + } + + /** + * Returns an instance of [RoleFlags] that has all bits set that are currently set in this + * [Builder]. + */ + public fun build(): RoleFlags = RoleFlags(value) + } + + internal object Serializer : KSerializer { + override val descriptor: SerialDescriptor = + PrimitiveSerialDescriptor("dev.kord.common.entity.RoleFlags", PrimitiveKind.INT) + + private val `delegate`: KSerializer = Int.serializer() + + override fun serialize(encoder: Encoder, `value`: RoleFlags) { + encoder.encodeSerializableValue(delegate, value.value) + } + + override fun deserialize(decoder: Decoder): RoleFlags = + RoleFlags(decoder.decodeSerializableValue(delegate)) + } +} + +/** + * Returns an instance of [RoleFlags] built with [RoleFlags.Builder]. + */ +public inline fun RoleFlags(builder: RoleFlags.Builder.() -> Unit = {}): RoleFlags { + contract { callsInPlace(builder, EXACTLY_ONCE) } + return RoleFlags.Builder().apply(builder).build() +} + +/** + * Returns an instance of [RoleFlags] that has all bits set that are set in any element of [flags]. + */ +public fun RoleFlags(vararg flags: RoleFlag): RoleFlags = RoleFlags { + flags.forEach { +it } +} + +/** + * Returns an instance of [RoleFlags] that has all bits set that are set in any element of [flags]. + */ +public fun RoleFlags(vararg flags: RoleFlags): RoleFlags = RoleFlags { + flags.forEach { +it } +} + +/** + * Returns an instance of [RoleFlags] that has all bits set that are set in any element of [flags]. + */ +public fun RoleFlags(flags: Iterable): RoleFlags = RoleFlags { + flags.forEach { +it } +} + +/** + * Returns an instance of [RoleFlags] that has all bits set that are set in any element of [flags]. + */ +@JvmName("RoleFlags0") +public fun RoleFlags(flags: Iterable): RoleFlags = RoleFlags { + flags.forEach { +it } +} diff --git a/common/src/commonMain/kotlin/entity/DiscordRole.kt b/common/src/commonMain/kotlin/entity/DiscordRole.kt index f25fbf88d97..99e41b680fd 100644 --- a/common/src/commonMain/kotlin/entity/DiscordRole.kt +++ b/common/src/commonMain/kotlin/entity/DiscordRole.kt @@ -1,9 +1,20 @@ +@file:Generate( + INT_FLAGS, name = "RoleFlag", + docUrl = "https://discord.com/developers/docs/topics/permissions#role-object-role-flags", + entries = [ + Entry("InPrompt", shift = 0, kDoc = "Role can be selected by members in an onboarding prompt."), + ], +) + package dev.kord.common.entity 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.ksp.Generate +import dev.kord.ksp.Generate.EntityType.INT_FLAGS +import dev.kord.ksp.Generate.Entry import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -21,6 +32,7 @@ public data class DiscordRole( val managed: Boolean, val mentionable: Boolean, val tags: Optional = Optional.Missing(), + val flags: RoleFlags, ) @Serializable diff --git a/common/src/commonTest/kotlin/json/PermissionsTest.kt b/common/src/commonTest/kotlin/json/PermissionsTest.kt index fc155d37397..0d5f6725914 100644 --- a/common/src/commonTest/kotlin/json/PermissionsTest.kt +++ b/common/src/commonTest/kotlin/json/PermissionsTest.kt @@ -39,6 +39,7 @@ class PermissionsTest { put("permissions", "123456789876543000000000000") put("managed", false) put("mentionable", false) + put("flags", 0) } val actual = Json.decodeFromJsonElement(DiscordRole.serializer(), expected) assertEquals( diff --git a/core/api/core.api b/core/api/core.api index 8a0a90912db..4d6d1ab94f7 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -4877,13 +4877,14 @@ public final class dev/kord/core/cache/data/ResolvedObjectsData$Companion { public final class dev/kord/core/cache/data/RoleData { public static final field Companion Ldev/kord/core/cache/data/RoleData$Companion; - public synthetic fun (ILdev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V - public fun (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;)V - public synthetic fun (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (ILdev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/RoleFlags;Lkotlinx/serialization/internal/SerializationConstructorMarker;)V + public fun (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/RoleFlags;)V + public synthetic fun (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/RoleFlags;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1 ()Ldev/kord/common/entity/Snowflake; public final fun component10 ()Z public final fun component11 ()Z public final fun component12 ()Ldev/kord/common/entity/optional/Optional; + public final fun component13 ()Ldev/kord/common/entity/RoleFlags; public final fun component2 ()Ldev/kord/common/entity/Snowflake; public final fun component3 ()Ljava/lang/String; public final fun component4 ()I @@ -4892,10 +4893,11 @@ public final class dev/kord/core/cache/data/RoleData { public final fun component7 ()Ldev/kord/common/entity/optional/Optional; public final fun component8 ()I public final fun component9 ()Ldev/kord/common/entity/Permissions; - public final fun copy (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;)Ldev/kord/core/cache/data/RoleData; - public static synthetic fun copy$default (Ldev/kord/core/cache/data/RoleData;Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;ILjava/lang/Object;)Ldev/kord/core/cache/data/RoleData; + public final fun copy (Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/RoleFlags;)Ldev/kord/core/cache/data/RoleData; + public static synthetic fun copy$default (Ldev/kord/core/cache/data/RoleData;Ldev/kord/common/entity/Snowflake;Ldev/kord/common/entity/Snowflake;Ljava/lang/String;IZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/optional/Optional;ILdev/kord/common/entity/Permissions;ZZLdev/kord/common/entity/optional/Optional;Ldev/kord/common/entity/RoleFlags;ILjava/lang/Object;)Ldev/kord/core/cache/data/RoleData; public fun equals (Ljava/lang/Object;)Z public final fun getColor ()I + public final fun getFlags ()Ldev/kord/common/entity/RoleFlags; public final fun getGuildId ()Ldev/kord/common/entity/Snowflake; public final fun getHoisted ()Z public final fun getIcon ()Ldev/kord/common/entity/optional/Optional; @@ -7006,6 +7008,7 @@ public final class dev/kord/core/entity/Role : dev/kord/core/behavior/RoleBehavi public fun fetchRoleOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getColor ()Ldev/kord/common/Color; public final fun getData ()Ldev/kord/core/cache/data/RoleData; + public final fun getFlags ()Ldev/kord/common/entity/RoleFlags; public fun getGuild ()Ldev/kord/core/behavior/GuildBehavior; public fun getGuildId ()Ldev/kord/common/entity/Snowflake; public final fun getHoisted ()Z diff --git a/core/src/commonMain/kotlin/cache/data/RoleData.kt b/core/src/commonMain/kotlin/cache/data/RoleData.kt index 9e7dab10bf3..44b6f37641a 100644 --- a/core/src/commonMain/kotlin/cache/data/RoleData.kt +++ b/core/src/commonMain/kotlin/cache/data/RoleData.kt @@ -2,10 +2,7 @@ package dev.kord.core.cache.data import dev.kord.cache.api.data.DataDescription import dev.kord.cache.api.data.description -import dev.kord.common.entity.DiscordGuildRole -import dev.kord.common.entity.DiscordRole -import dev.kord.common.entity.Permissions -import dev.kord.common.entity.Snowflake +import dev.kord.common.entity.* import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.map import kotlinx.serialization.Serializable @@ -23,7 +20,8 @@ public data class RoleData( val permissions: Permissions, val managed: Boolean, val mentionable: Boolean, - val tags: Optional = Optional.Missing() + val tags: Optional = Optional.Missing(), + val flags: RoleFlags, ) { public companion object { public val description: DataDescription = description(RoleData::id) @@ -41,7 +39,9 @@ public data class RoleData( permissions, managed, mentionable, - tags.map { RoleTagsData.from(it) }) + tags.map { RoleTagsData.from(it) }, + flags, + ) } public fun from(entity: DiscordGuildRole): RoleData = from(entity.guildId, entity.role) diff --git a/core/src/commonMain/kotlin/entity/Role.kt b/core/src/commonMain/kotlin/entity/Role.kt index c2b623a3272..ceccb661ba5 100644 --- a/core/src/commonMain/kotlin/entity/Role.kt +++ b/core/src/commonMain/kotlin/entity/Role.kt @@ -2,6 +2,7 @@ package dev.kord.core.entity import dev.kord.common.Color import dev.kord.common.entity.Permissions +import dev.kord.common.entity.RoleFlags import dev.kord.common.entity.Snowflake import dev.kord.common.entity.optional.unwrap import dev.kord.core.Kord @@ -56,6 +57,9 @@ public data class Role( */ public val tags: RoleTags? get() = data.tags.unwrap { RoleTags(it, guildId, kord) } + /** The [RoleFlags] of this role. */ + public val flags: RoleFlags get() = data.flags + override fun compareTo(other: Entity): Int = when (other) { is Role -> compareBy { it.rawPosition }.thenBy { it.guildId }.compare(this, other) else -> super.compareTo(other) diff --git a/core/src/commonTest/kotlin/live/LiveGuildTest.kt b/core/src/commonTest/kotlin/live/LiveGuildTest.kt index e0a1cb38ca5..ac205b5426c 100644 --- a/core/src/commonTest/kotlin/live/LiveGuildTest.kt +++ b/core/src/commonTest/kotlin/live/LiveGuildTest.kt @@ -267,7 +267,8 @@ class LiveGuildTest : AbstractLiveEntityTest() { position = 0, permissions = Permissions(Permission.BanMembers), managed = false, - mentionable = false + mentionable = false, + flags = RoleFlags(), ) ), 0 @@ -299,7 +300,8 @@ class LiveGuildTest : AbstractLiveEntityTest() { position = 0, permissions = Permissions(Permission.BanMembers), managed = false, - mentionable = false + mentionable = false, + flags = RoleFlags(), ) ), 0 diff --git a/core/src/commonTest/kotlin/live/LiveRoleTest.kt b/core/src/commonTest/kotlin/live/LiveRoleTest.kt index 3f19e64bf21..bfecf840b59 100644 --- a/core/src/commonTest/kotlin/live/LiveRoleTest.kt +++ b/core/src/commonTest/kotlin/live/LiveRoleTest.kt @@ -41,7 +41,8 @@ class LiveRoleTest : AbstractLiveEntityTest() { position = 0, permissions = Permissions(Permission.CreateInstantInvite), managed = false, - mentionable = false + mentionable = false, + flags = RoleFlags(), ) ) ) @@ -70,7 +71,8 @@ class LiveRoleTest : AbstractLiveEntityTest() { position = 0, permissions = Permissions(Permission.BanMembers), managed = false, - mentionable = false + mentionable = false, + flags = RoleFlags(), ) ), 0 diff --git a/ksp-processors/src/main/kotlin/generation/bitflags/Documentation.kt b/ksp-processors/src/main/kotlin/generation/bitflags/Documentation.kt index 2fe79e812e3..0445a7f46a2 100644 --- a/ksp-processors/src/main/kotlin/generation/bitflags/Documentation.kt +++ b/ksp-processors/src/main/kotlin/generation/bitflags/Documentation.kt @@ -1,5 +1,6 @@ package dev.kord.ksp.generation.bitflags +import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.TypeSpec import dev.kord.ksp.generation.GenerationEntity.BitFlags import dev.kord.ksp.generation.shared.GenerationContext @@ -10,7 +11,9 @@ internal fun TypeSpec.Builder.addCollectionKDoc() = addKdoc( entityCN, // %1T: flag ClassName collectionCN, // %2T: collection ClassName entityCN.nestedClass(entriesDistinctByValue[0].name), // %3T: entry 0 ClassName - entityCN.nestedClass(entriesDistinctByValue[1].name), // %4T: entry 1 ClassName + // %4L: CodeBlock with entry 1 ClassName or `Flag.fromShift(22)` + entriesDistinctByValue.getOrNull(1)?.let { CodeBlock.of("%T", entityCN.nestedClass(it.name)) } + ?: CodeBlock.of("%T.fromShift(22)", entityCN), entityCN.nestedClass("Unknown"), // %5T: Unknown ClassName builderCN, // %6T: Builder ClassName ) @@ -27,7 +30,7 @@ private val BitFlags.docStringFormat: String You can create an instance of [%2T] using the following methods: ```kotlin //·from·individual·%1Ts - val·${collection}1·=·%2T(%3T,·%4T) + val·${collection}1·=·%2T(%3T,·%4L) //·from·an·Iterable val·iterable:·Iterable<%1T>·=·TODO() @@ -37,7 +40,7 @@ private val BitFlags.docStringFormat: String val·${collection}3·=·%2T·{ +${collection}2 +%3T - -%4T + -%4L } ``` @@ -55,7 +58,7 @@ private val BitFlags.docStringFormat: String All [%2T] objects can use `+`/`-` operators: ```kotlin val·${collection}1·=·$collection·+·%3T - val·${collection}2·=·$collection·-·%4T + val·${collection}2·=·$collection·-·%4L val·${collection}3·=·${collection}1·+·${collection}2 ``` @@ -64,7 +67,7 @@ private val BitFlags.docStringFormat: String You can use the [contains] operator to check whether an instance of [%2T] contains specific [%1T]s: ```kotlin val·has%1T·=·%3T·in·$collection - val·has%2T·=·%2T(%3T,·%4T)·in·$collection + val·has%2T·=·%2T(%3T,·%4L)·in·$collection ``` ##·Unknown·[%1T]s