Skip to content

Commit

Permalink
Compatibility for Permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
lukellmann committed Aug 21, 2023
1 parent 4eef5bf commit 4e35983
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 51 deletions.
35 changes: 32 additions & 3 deletions common/api/common.api
Original file line number Diff line number Diff line change
Expand Up @@ -7869,6 +7869,7 @@ public final class dev/kord/common/entity/OverwriteType$Unknown : dev/kord/commo
public abstract class dev/kord/common/entity/Permission {
public static final field Companion Ldev/kord/common/entity/Permission$Companion;
public synthetic fun <init> (ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ldev/kord/common/DiscordBitSet;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun equals (Ljava/lang/Object;)Z
public final fun getCode ()Ldev/kord/common/DiscordBitSet;
public final fun getShift ()I
Expand All @@ -7886,6 +7887,10 @@ public final class dev/kord/common/entity/Permission$Administrator : dev/kord/co
public static final field INSTANCE Ldev/kord/common/entity/Permission$Administrator;
}

public final class dev/kord/common/entity/Permission$All : dev/kord/common/entity/Permission {
public static final field INSTANCE Ldev/kord/common/entity/Permission$All;
}

public final class dev/kord/common/entity/Permission$AttachFiles : dev/kord/common/entity/Permission {
public static final field INSTANCE Ldev/kord/common/entity/Permission$AttachFiles;
}
Expand All @@ -7901,6 +7906,7 @@ public final class dev/kord/common/entity/Permission$ChangeNickname : dev/kord/c
public final class dev/kord/common/entity/Permission$Companion {
public final fun fromShift (I)Ldev/kord/common/entity/Permission;
public final fun getEntries ()Ljava/util/List;
public final fun getValues ()Ljava/util/Set;
}

public final class dev/kord/common/entity/Permission$Connect : dev/kord/common/entity/Permission {
Expand Down Expand Up @@ -8024,6 +8030,8 @@ public final class dev/kord/common/entity/Permission$Stream : dev/kord/common/en
}

public final class dev/kord/common/entity/Permission$Unknown : dev/kord/common/entity/Permission {
public fun <init> (Ldev/kord/common/DiscordBitSet;)V
public fun <init> ([J)V
}

public final class dev/kord/common/entity/Permission$UseApplicationCommands : dev/kord/common/entity/Permission {
Expand Down Expand Up @@ -8071,7 +8079,9 @@ public final class dev/kord/common/entity/Permission$ViewGuildInsights : dev/kor
}

public final class dev/kord/common/entity/PermissionKt {
public static final synthetic fun PermissionWithIterable (Ljava/lang/Iterable;)Ldev/kord/common/entity/Permissions;
public static final fun Permissions (Ljava/lang/Iterable;)Ldev/kord/common/entity/Permissions;
public static final fun Permissions (Ljava/lang/String;)Ldev/kord/common/entity/Permissions;
public static final fun Permissions (Lkotlin/jvm/functions/Function1;)Ldev/kord/common/entity/Permissions;
public static final fun Permissions ([Ldev/kord/common/entity/Permission;)Ldev/kord/common/entity/Permissions;
public static final fun Permissions ([Ldev/kord/common/entity/Permissions;)Ldev/kord/common/entity/Permissions;
Expand All @@ -8081,6 +8091,8 @@ public final class dev/kord/common/entity/PermissionKt {

public final class dev/kord/common/entity/Permissions {
public static final field Companion Ldev/kord/common/entity/Permissions$Companion;
public static final field NewCompanion Ldev/kord/common/entity/Permissions$NewCompanion;
public fun <init> (Ldev/kord/common/DiscordBitSet;)V
public final fun component1 ()Ldev/kord/common/DiscordBitSet;
public final fun contains (Ldev/kord/common/entity/Permission;)Z
public final fun contains (Ldev/kord/common/entity/Permissions;)Z
Expand All @@ -8103,19 +8115,36 @@ public final class dev/kord/common/entity/Permissions$Builder {
public fun <init> (Ldev/kord/common/DiscordBitSet;)V
public synthetic fun <init> (Ldev/kord/common/DiscordBitSet;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun build ()Ldev/kord/common/entity/Permissions;
public final fun flags ()Ldev/kord/common/entity/Permissions;
public final fun unaryMinus (Ldev/kord/common/entity/Permission;)V
public final fun unaryMinus (Ldev/kord/common/entity/Permissions;)V
public final fun unaryPlus (Ldev/kord/common/entity/Permission;)V
public final fun unaryPlus (Ldev/kord/common/entity/Permissions;)V
}

public final class dev/kord/common/entity/Permissions$Companion {
public final class dev/kord/common/entity/Permissions$Companion : kotlinx/serialization/KSerializer {
public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ldev/kord/common/entity/Permissions;
public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object;
public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor;
public fun serialize (Lkotlinx/serialization/encoding/Encoder;Ldev/kord/common/entity/Permissions;)V
public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class dev/kord/common/entity/Permissions$NewCompanion {
public final fun serializer ()Lkotlinx/serialization/KSerializer;
}

public final class dev/kord/common/entity/Permissions$PermissionsBuilder {
public fun <init> (Ldev/kord/common/DiscordBitSet;)V
public final fun permissions ()Ldev/kord/common/entity/Permissions;
public final fun unaryMinus (Ldev/kord/common/entity/Permission;)V
public final fun unaryMinus (Ldev/kord/common/entity/Permissions;)V
public final fun unaryPlus (Ldev/kord/common/entity/Permission;)V
public final fun unaryPlus (Ldev/kord/common/entity/Permissions;)V
}

public final class dev/kord/common/entity/PermissionsKt {
public static final fun getALL (Ldev/kord/common/entity/Permissions$Companion;)Ldev/kord/common/entity/Permissions;
public static final fun getALL (Ldev/kord/common/entity/Permissions$NewCompanion;)Ldev/kord/common/entity/Permissions;
}

public abstract class dev/kord/common/entity/PremiumTier {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import dev.kord.common.EmptyBitSet
import kotlin.LazyThreadSafetyMode.PUBLICATION
import kotlin.contracts.InvocationKind.EXACTLY_ONCE
import kotlin.contracts.contract
import kotlin.jvm.JvmField
import kotlin.jvm.JvmName
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
Expand All @@ -22,49 +23,103 @@ import kotlinx.serialization.encoding.Encoder
* See [Permission]s in the
* [Discord Developer Documentation](https://discord.com/developers/docs/topics/permissions).
*/
public sealed class Permission(
public sealed class Permission {
private val isProper: Boolean
private val _shift: Int // only use if isProper == true
private val _code: DiscordBitSet? // only non-null if isProper == false

private constructor(shift: Int) {
require(shift >= 0) { """shift has to be >= 0 but was $shift""" }
isProper = true
_shift = shift
_code = null
}

private constructor(code: DiscordBitSet) {
var singleBitIsSet = false
var shift = -1
for (i in 0..<code.size) {
if (code[i]) {
if (singleBitIsSet) {
singleBitIsSet = false
break
} else {
singleBitIsSet = true
shift = i
}
}
}
if (singleBitIsSet) {
isProper = true
_shift = shift.also { if (it < 0) throw AssertionError() }
_code = null
} else {
isProper = false
_shift = -1
_code = code
}
}

/**
* The position of the bit that is set in this [Permission]. This is always >= 0.
*/
public val shift: Int,
) {
init {
require(shift >= 0) { """shift has to be >= 0 but was $shift""" }
}
public val shift: Int
get() = if (isProper) _shift else throw IllegalArgumentException(
"$this is not a proper instance of 'Permission' because multiple bits are set."
)

/**
* The raw code used by Discord.
*/
public val code: DiscordBitSet
get() = EmptyBitSet().also { it[shift] = true }
get() = if (isProper) EmptyBitSet().also { it[_shift] = true } else _code!!

/**
* Returns an instance of [Permissions] that has all bits set that are set in `this` and [flag].
*/
public operator fun plus(flag: Permission): Permissions = Permissions(this.code + flag.code)
public operator fun plus(flag: Permission): Permissions = Permissions(this.code + flag.code, null)

/**
* Returns an instance of [Permissions] that has all bits set that are set in `this` and
* [flags].
*/
public operator fun plus(flags: Permissions): Permissions = Permissions(this.code + flags.code)
public operator fun plus(flags: Permissions): Permissions = Permissions(this.code + flags.code, null)

final override fun equals(other: Any?): Boolean = this === other ||
(other is Permission && this.shift == other.shift)
(other is Permission
&& (this.isProper == other.isProper)
&& (if (isProper) this._shift == other._shift else this._code == other._code))

final override fun hashCode(): Int = shift.hashCode()
final override fun hashCode(): Int = if (isProper) _shift.hashCode() else _code.hashCode()

final override fun toString(): String = if (this is Unknown) "Permission.Unknown(shift=$shift)"
final override fun toString(): String = if (this is Unknown)
(if (isProper) "Permission.Unknown(shift=$_shift)" else "Permission.Unknown(code=$_code)")
else "Permission.${this::class.simpleName}"

/**
* An unknown [Permission].
*
* This is used as a fallback for [Permission]s that haven't been added to Kord yet.
*/
public class Unknown internal constructor(
shift: Int,
) : Permission(shift)
public class Unknown : Permission {
internal constructor(shift: Int) : super(shift)

// TODO uncomment annotation in Permissions.kt and delete this file when these constructors are removed after
// deprecation cycle
@Deprecated(
"Construct an unknown 'Permission' with 'Permission.fromShift()' instead.",
ReplaceWith("Permission.fromShift(TODO())", imports = ["dev.kord.common.entity.Permission"]),
DeprecationLevel.WARNING,
)
public constructor(code: DiscordBitSet) : super(code)

@Deprecated(
"Construct an unknown 'Permission' with 'Permission.fromShift()' instead.",
ReplaceWith("Permission.fromShift(TODO())", imports = ["dev.kord.common.entity.Permission"]),
DeprecationLevel.WARNING,
)
public constructor(vararg values: Long) : super(DiscordBitSet(values))
}

/**
* Allows creation of instant invites.
Expand Down Expand Up @@ -309,6 +364,15 @@ public sealed class Permission(
*/
public object SendVoiceMessages : Permission(46)

// TODO uncomment annotation in Permissions.kt and delete this file when this object is removed after deprecation
// cycle
@Deprecated(
"'Permission.All' is not a proper 'Permission' instance. Replace with 'Permissions.ALL'.",
ReplaceWith("Permissions.ALL", imports = ["dev.kord.common.entity.Permissions", "dev.kord.common.entity.ALL"]),
DeprecationLevel.WARNING,
)
public object All : Permission(Permissions.ALL.code)

public companion object {
/**
* A [List] of all known [Permission]s.
Expand Down Expand Up @@ -363,6 +427,14 @@ public sealed class Permission(
)
}

// TODO uncomment annotation in Permissions.kt and delete this file when this property is removed after
// deprecation cycle
@Deprecated(
"Renamed to 'entries'.",
ReplaceWith("Permission.entries", imports = ["dev.kord.common.entity.Permission"]),
DeprecationLevel.WARNING,
)
public val values: Set<Permission> get() = entries.toSet()

/**
* Returns an instance of [Permission] with [Permission.shift] equal to the specified
Expand Down Expand Up @@ -490,7 +562,18 @@ public class Permissions internal constructor(
* The raw code used by Discord.
*/
public val code: DiscordBitSet,
@Suppress("UNUSED_PARAMETER") unused: Nothing?,
) {
// TODO uncomment annotation in Permissions.kt and delete this file when this constructor is removed after
// deprecation cycle
@Deprecated(
"Don't construct an instance of 'Permissions' from a raw code. Use the factory functions described in the " +
"documentation instead.",
ReplaceWith("Permissions.Builder(code).build()", "dev.kord.common.entity.Permissions"),
DeprecationLevel.WARNING,
)
public constructor(code: DiscordBitSet) : this(code, null)

/**
* A [Set] of all [Permission]s contained in this instance of [Permissions].
*/
Expand All @@ -514,25 +597,25 @@ public class Permissions internal constructor(
/**
* Returns an instance of [Permissions] that has all bits set that are set in `this` and [flag].
*/
public operator fun plus(flag: Permission): Permissions = Permissions(this.code + flag.code)
public operator fun plus(flag: Permission): Permissions = Permissions(this.code + flag.code, null)

/**
* Returns an instance of [Permissions] that has all bits set that are set in `this` and
* [flags].
*/
public operator fun plus(flags: Permissions): Permissions = Permissions(this.code + flags.code)
public operator fun plus(flags: Permissions): Permissions = Permissions(this.code + flags.code, null)

/**
* Returns an instance of [Permissions] that has all bits set that are set in `this` except the
* bits that are set in [flag].
*/
public operator fun minus(flag: Permission): Permissions = Permissions(this.code - flag.code)
public operator fun minus(flag: Permission): Permissions = Permissions(this.code - flag.code, null)

/**
* Returns an instance of [Permissions] that has all bits set that are set in `this` except the
* bits that are set in [flags].
*/
public operator fun minus(flags: Permissions): Permissions = Permissions(this.code - flags.code)
public operator fun minus(flags: Permissions): Permissions = Permissions(this.code - flags.code, null)

/**
* Returns a copy of this instance of [Permissions] modified with [builder].
Expand Down Expand Up @@ -564,7 +647,21 @@ public class Permissions internal constructor(
@Suppress(names = arrayOf("DeprecatedCallableAddReplaceWith"))
@Deprecated(message =
"Permissions is no longer a data class. Deprecated without a replacement.")
public fun copy(code: DiscordBitSet = this.code): Permissions = Permissions(code)
public fun copy(code: DiscordBitSet = this.code): Permissions = Permissions(code, null)

@Deprecated(
"Renamed to 'Builder'.",
ReplaceWith("Permissions.Builder", imports = ["dev.kord.common.entity.Permissions"]),
DeprecationLevel.WARNING,
)
public class PermissionsBuilder(code: DiscordBitSet) {
private val delegate = Builder(code)
public operator fun Permissions.unaryPlus(): Unit = with(delegate) { unaryPlus() }
public operator fun Permissions.unaryMinus(): Unit = with(delegate) { unaryMinus() }
public operator fun Permission.unaryPlus(): Unit = with(delegate) { unaryPlus() }
public operator fun Permission.unaryMinus(): Unit = with(delegate) { unaryMinus() }
public fun permissions(): Permissions = delegate.build()
}

public class Builder(
private val code: DiscordBitSet = EmptyBitSet(),
Expand Down Expand Up @@ -601,16 +698,7 @@ public class Permissions internal constructor(
* Returns an instance of [Permissions] that has all bits set that are currently set in this
* [Builder].
*/
public fun build(): Permissions = Permissions(code.copy())

/**
* @suppress
*/
@Deprecated(
message = "Renamed to 'build'",
replaceWith = ReplaceWith(expression = "this.build()", imports = arrayOf()),
)
public fun flags(): Permissions = build()
public fun build(): Permissions = Permissions(code.copy(), null)
}

internal object Serializer : KSerializer<Permissions> {
Expand All @@ -625,7 +713,28 @@ public class Permissions internal constructor(
}

override fun deserialize(decoder: Decoder): Permissions =
Permissions(decoder.decodeSerializableValue(delegate))
Permissions(decoder.decodeSerializableValue(delegate), null)
}

public companion object NewCompanion {

@Suppress("DEPRECATION")
@Deprecated(
"Renamed to 'NewCompanion', which no longer implements 'KSerializer<Permissions>'.",
ReplaceWith("Permissions.serializer()", imports = ["dev.kord.common.entity.Permissions"]),
DeprecationLevel.WARNING,
)
@JvmField
public val Companion: Companion = Companion()
}

@Deprecated(
"Renamed to 'NewCompanion', which no longer implements 'KSerializer<Permissions>'.",
ReplaceWith("Permissions.serializer()", imports = ["dev.kord.common.entity.Permissions"]),
DeprecationLevel.WARNING,
)
public class Companion internal constructor() : KSerializer<Permissions> by Serializer {
public fun serializer(): KSerializer<Permissions> = this
}
}

Expand Down Expand Up @@ -669,3 +778,20 @@ public fun Permissions(flags: Iterable<Permission>): Permissions = Permissions {
public fun Permissions(flags: Iterable<Permissions>): Permissions = Permissions {
flags.forEach { +it }
}

// TODO uncomment annotation in Permissions.kt and delete this file when these functions are removed after deprecation
// cycle
@Suppress("FunctionName")
@Deprecated("Binary compatibility, keep for some releases.", level = DeprecationLevel.HIDDEN)
public fun PermissionWithIterable(flags: Iterable<Permissions>): Permissions = Permissions(flags)

@Deprecated(
"Don't construct an instance of 'Permissions' from a raw value. Use the factory functions described in the " +
"documentation instead.",
ReplaceWith(
"Permissions.Builder(DiscordBitSet(value)).build()",
imports = ["dev.kord.common.entity.Permissions", "dev.kord.common.DiscordBitSet"],
),
DeprecationLevel.WARNING,
)
public fun Permissions(value: String): Permissions = Permissions(DiscordBitSet(value), null)
Loading

0 comments on commit 4e35983

Please sign in to comment.