diff --git a/common/src/commonMain/kotlin/entity/Snowflake.kt b/common/src/commonMain/kotlin/entity/Snowflake.kt index 07a1f2a06ab..fd8572c4425 100644 --- a/common/src/commonMain/kotlin/entity/Snowflake.kt +++ b/common/src/commonMain/kotlin/entity/Snowflake.kt @@ -1,6 +1,7 @@ package dev.kord.common.entity import dev.kord.common.entity.Snowflake.Companion.validValues +import kotlin.jvm.JvmInline import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlinx.serialization.KSerializer @@ -16,23 +17,15 @@ import kotlin.time.TimeMark * A unique identifier for entities [used by Discord](https://discord.com/developers/docs/reference#snowflakes). * * Snowflakes are IDs with a [timestamp], which makes them [comparable][compareTo] based on their timestamp. + * + * @constructor Values are [coerced in][coerceIn] [validValues]. */ +@JvmInline @Serializable(with = Snowflake.Serializer::class) -public class Snowflake : Comparable { +public value class Snowflake(public val value: ULong) : Comparable { - /** - * The raw value of this Snowflake as specified by the - * [Discord Developer Documentation](https://discord.com/developers/docs/reference#snowflakes). - */ - public val value: ULong - - /** - * Creates a Snowflake from a given ULong [value]. - * - * Values are [coerced in][coerceIn] [validValues]. - */ - public constructor(value: ULong) { - this.value = value.coerceIn(validValues) + init { + value.coerceIn(validValues) } /** @@ -146,11 +139,8 @@ public class Snowflake : Comparable { return this.value.compareTo(other.value) } - override fun equals(other: Any?): Boolean = other is Snowflake && this.value == other.value - override fun hashCode(): Int = value.hashCode() override fun toString(): String = value.toString() - public companion object { // see https://discord.com/developers/docs/reference#snowflakes-snowflake-id-format-structure-left-to-right @@ -192,7 +182,7 @@ public class Snowflake : Comparable { * * Note that this range might change in the future. */ - public val validValues: ULongRange = ULong.MIN_VALUE..Long.MAX_VALUE.toULong() // 0..9223372036854775807 + public val validValues: ULongRange = ULong.MIN_VALUE..ULong.MAX_VALUE // 0..9223372036854775807 /** * The minimum value a Snowflake can hold. diff --git a/common/src/commonMain/kotlin/entity/optional/OptionalSnowflake.kt b/common/src/commonMain/kotlin/entity/optional/OptionalSnowflake.kt index f8fbbdb9ef9..ab2125a1e48 100644 --- a/common/src/commonMain/kotlin/entity/optional/OptionalSnowflake.kt +++ b/common/src/commonMain/kotlin/entity/optional/OptionalSnowflake.kt @@ -68,14 +68,12 @@ public sealed class OptionalSnowflake { * Represents a [Snowflake] field that was assigned a non-null value in the serialized entity. * Equality and hashcode is implemented through its [value]. * - * @param uLongValue the raw value this optional wraps. + * @param snowflake the raw value this optional wraps. * See [Snowflake.value] and [Snowflake.validValues] for more details. */ - public class Value(private val uLongValue: ULong) : OptionalSnowflake() { + public class Value(private val snowflake: Snowflake) : OptionalSnowflake() { - public constructor(value: Snowflake) : this(value.value) - - override val value: Snowflake get() = Snowflake(uLongValue) + override val value: Snowflake get() = snowflake /** * Destructures this optional to its [value]. @@ -96,7 +94,7 @@ public sealed class OptionalSnowflake { override val descriptor: SerialDescriptor = ULong.serializer().descriptor override fun deserialize(decoder: Decoder): OptionalSnowflake = - Value(decoder.decodeInline(descriptor).decodeLong().toULong()) + Value(Snowflake(decoder.decodeInline(descriptor).decodeLong().toULong())) override fun serialize(encoder: Encoder, value: OptionalSnowflake) = when (value) { Missing -> Unit // ignore value @@ -114,7 +112,7 @@ public val OptionalSnowflake?.value: Snowflake? OptionalSnowflake.Missing, null -> null } -public fun Snowflake.optionalSnowflake(): OptionalSnowflake.Value = OptionalSnowflake.Value(this.value) +public fun Snowflake.optionalSnowflake(): OptionalSnowflake.Value = OptionalSnowflake.Value(this) @JvmName("optionalNullable") public fun Snowflake?.optionalSnowflake(): OptionalSnowflake.Value? = this?.optionalSnowflake() diff --git a/common/src/commonMain/kotlin/entity/optional/delegate/OptionalSnowflakeDelegate.kt b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalSnowflakeDelegate.kt index 756689e8972..d181e206ebd 100644 --- a/common/src/commonMain/kotlin/entity/optional/delegate/OptionalSnowflakeDelegate.kt +++ b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalSnowflakeDelegate.kt @@ -19,7 +19,7 @@ public fun KMutableProperty0.delegate(): ReadWriteProperty, value: Snowflake?) { val optional = if (value == null) OptionalSnowflake.Missing - else OptionalSnowflake.Value(value.value) + else OptionalSnowflake.Value(value) this@delegate.set(optional) } } diff --git a/core/src/commonTest/kotlin/live/AbstractLiveEntityTest.kt b/core/src/commonTest/kotlin/live/AbstractLiveEntityTest.kt index f6620c84c4b..6fe10ad9946 100644 --- a/core/src/commonTest/kotlin/live/AbstractLiveEntityTest.kt +++ b/core/src/commonTest/kotlin/live/AbstractLiveEntityTest.kt @@ -70,7 +70,7 @@ abstract class AbstractLiveEntityTest { protected lateinit var kord: Kord - protected lateinit var guildId: Snowflake + protected var guildId: Snowflake = Snowflake.min lateinit var live: LIVE diff --git a/core/src/jvmTest/kotlin/rest/RestTest.kt b/core/src/jvmTest/kotlin/rest/RestTest.kt index dac8135d779..4a2cd8f415d 100644 --- a/core/src/jvmTest/kotlin/rest/RestTest.kt +++ b/core/src/jvmTest/kotlin/rest/RestTest.kt @@ -51,15 +51,15 @@ class RestServiceTest { private lateinit var kord: Kord //created guild id - private lateinit var guildId: Snowflake + private var guildId: Snowflake = Snowflake.min private lateinit var guild: Guild //created channel id - private lateinit var channelId: Snowflake + private var channelId: Snowflake = Snowflake.min private lateinit var channel: TextChannel - private lateinit var userId: Snowflake + private var userId: Snowflake = Snowflake.min @BeforeAll fun setup() = runBlocking {