Skip to content

Commit

Permalink
Migrated Snowflake to inline class
Browse files Browse the repository at this point in the history
  • Loading branch information
zTrap committed Oct 24, 2023
1 parent a4f7143 commit 527f17c
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 30 deletions.
26 changes: 8 additions & 18 deletions common/src/commonMain/kotlin/entity/Snowflake.kt
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<Snowflake> {
public value class Snowflake(public val value: ULong) : Comparable<Snowflake> {

/**
* 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)
}

/**
Expand Down Expand Up @@ -146,11 +139,8 @@ public class Snowflake : Comparable<Snowflake> {
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

Expand Down Expand Up @@ -192,7 +182,7 @@ public class Snowflake : Comparable<Snowflake> {
*
* 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Expand All @@ -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
Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public fun KMutableProperty0<OptionalSnowflake>.delegate(): ReadWriteProperty<An

override fun setValue(thisRef: Any?, property: KProperty<*>, value: Snowflake?) {
val optional = if (value == null) OptionalSnowflake.Missing
else OptionalSnowflake.Value(value.value)
else OptionalSnowflake.Value(value)
this@delegate.set(optional)
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/commonTest/kotlin/live/AbstractLiveEntityTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ abstract class AbstractLiveEntityTest<LIVE : AbstractLiveKordEntity> {

protected lateinit var kord: Kord

protected lateinit var guildId: Snowflake
protected var guildId: Snowflake = Snowflake.min

lateinit var live: LIVE

Expand Down
6 changes: 3 additions & 3 deletions core/src/jvmTest/kotlin/rest/RestTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 527f17c

Please sign in to comment.