Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

提供 ID 和 Timestamp 的属性委托API #688

Merged
merged 2 commits into from
May 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 51 additions & 5 deletions simbot-api/src/main/kotlin/love/forte/simbot/ID.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import love.forte.simbot.delegate.*
import love.forte.simbot.utils.RandomIDUtil
import java.math.BigDecimal
import java.math.BigInteger
Expand All @@ -43,7 +44,10 @@ import kotlin.random.asKotlinRandom
* 比如 `FloatID`,没有人会使用浮点数作为ID的。
*
*/
@RequiresOptIn("An ID type that may have no practical use may be removed in the future", level = RequiresOptIn.Level.WARNING)
@RequiresOptIn(
"An ID type that may have no practical use may be removed in the future",
level = RequiresOptIn.Level.WARNING
)
@Retention(AnnotationRetention.BINARY)
@MustBeDocumented
public annotation class ConfusedIDType
Expand All @@ -59,8 +63,35 @@ public annotation class ConfusedIDType
*
* [ID] 是 [可排序的][Comparable]。
*
* ## 简单包装器
*
* ### 序列化
* [ID] 是一种简单包装器类型,因此建议那些对外公开的 [ID] 属性使用 **即用即造** 的形式,即不会急切的初始化属性,
* 而是每次获取时临时创建。
*
* 例如:
*
* ```kotlin
* val idContainer = ...
*
* // 下面会产生3个ID对象
* useID(idContainer.id)
* useID(idContainer.id)
* useID(idContainer.id)
* ```
*
* 也因此,大多数通过属性获取 [ID] 的情况下建议通过局部变量保存以复用。
*
* ```kotlin
* val idContainer = ...
* val id = idContainer.id
*
* // 重复利用
* useID(id)
* useID(id)
* useID(id)
* ```
*
* ## 序列化
*
* [ID] 支持序列化, 且 [ID] 的序列化器应当都是一个 `primitive` 序列化器。
* [ID] 序列化后都不应是结构体, 而是一个值类型。
Expand Down Expand Up @@ -96,7 +127,7 @@ public annotation class ConfusedIDType
*
* 此序列化其会永远将ID视为字符串作为序列化目标。
*
* ### 构造
* ## 构造
*
* [ID] 提供了名为 `ID` 的后缀扩展属性来将某个值构造为 [ID] 类型,
* 其中你需要关系的是几个常见的ID类型,即字符串类型和各整型类型的ID。
Expand Down Expand Up @@ -125,17 +156,30 @@ public annotation class ConfusedIDType
* - [Long.ID]
* - [CharSequence.ID]
*
* ### 随机ID
* ## 随机ID
*
* 如果你需要获取一个随机的ID,可以考虑使用 [randomID]. [randomID] 内使用 [RandomIDUtil.randomID]
* 生成一个 _类UUID风格_ 的随机字符串并包装为 [ID] 并返回.
*
* 不过需要注意,这个随机ID返回的内容并非标准的HEX字符串或UUID字符串。
*
* ### 具体类型
* ## 具体类型
*
* [ID] 是一个抽象类型,有关其他具体实现类型参阅它们各自的说明。
*
*
* ## 属性委托
*
* 面向公开属性的场景 [ID] 提供了一些更简便的属性委托API来简化代码。
*
* 有关它们的说明参考
* - [IntIDDelegate.getValue]
* - [UIntIDDelegate.getValue]
* - [LongIDDelegate.getValue]
* - [ULongIDDelegate.getValue]
* - [CharSequenceIDDelegate.getValue]
*
*
* @see CharSequenceID
* @see IntID
* @see LongID
Expand Down Expand Up @@ -407,6 +451,7 @@ public sealed class NumericalID<N : Number> : ID(), NumberSimilarly {
}
}
}

other is UIntID -> return -other.compareTo(this)
other is ULongID -> return -other.compareTo(this)
else -> return toString().compareTo(other.toString())
Expand Down Expand Up @@ -1269,3 +1314,4 @@ public interface NumberSimilarly {
*/
public fun toByte(): Byte
}

52 changes: 35 additions & 17 deletions simbot-api/src/main/kotlin/love/forte/simbot/Timestamp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import love.forte.simbot.delegate.TimestampDelegate
import love.forte.simbot.delegate.getValue
import java.time.Instant
import kotlin.reflect.KProperty

/**
* 一个 **时间戳** 。
Expand All @@ -30,6 +31,39 @@ import kotlin.reflect.KProperty
* 而是一个不被支持的默认值。
* 通过 [Timestamp] 你可以直接通过 [isSupport] 对支持情况进行判断。
*
* ## 简单包装器
*
* [Timestamp] 是一种简单包装器类型,因此建议那些对外公开的 [Timestamp] 属性使用 **即用即造** 的形式,即不会急切的初始化属性,
* 而是每次获取时临时创建。
*
* 例如:
*
* ```kotlin
* val container = ...
*
* // 下面会产生3个 Timestamp 对象
* useTimestamp(container.timestamp)
* useTimestamp(container.timestamp)
* useTimestamp(container.timestamp)
* ```
*
* 也因此,大多数通过属性获取 [Timestamp] 的情况下建议通过局部变量保存以复用。
*
* ```kotlin
* val container = ...
* val timestamp = container.timestamp
*
* // 重复利用
* useTimestamp(timestamp)
* useTimestamp(timestamp)
* useTimestamp(timestamp)
* ```
*
* ## 属性委托
*
* 面向公开属性的场景 [Timestamp] 提供了一些更简便的属性委托API来简化代码。
* 有关它们的说明参考 [TimestampDelegate.getValue]
*
* @see InstantTimestamp
* @author ForteScarlet
*/
Expand Down Expand Up @@ -221,19 +255,3 @@ public object TimestampSerializer : KSerializer<Timestamp> {
}

}

/**
* 将一个**毫秒时间戳**代理为 [Timestamp].
*
* e.g.
* ```kotlin
* val now: Timestamp by System.currentTimeMillis()
* ```
*
* @since 3.1.0
*
* @see Timestamp
*
*/
@Suppress("NOTHING_TO_INLINE")
public inline operator fun Long.getValue(o: Any?, property: KProperty<*>?): Timestamp = Timestamp.byMillisecond(this)
Loading