4
4
* Project https://github.com/simple-robot/simpler-robot
5
5
6
6
*
7
- * This file is part of the Simple Robot Library.
7
+ * This file is part of the Simple Robot Library (Alias: simple-robot, simbot, etc.) .
8
8
*
9
9
* This program is free software: you can redistribute it and/or modify
10
10
* it under the terms of the GNU Lesser General Public License as published by
21
21
*
22
22
*/
23
23
24
+ @file:JvmName(" Identifies" )
25
+ @file:JvmMultifileClass
26
+
24
27
package love.forte.simbot.common.id
25
28
26
- import kotlinx.serialization.KSerializer
27
- import kotlinx.serialization.Serializable
29
+ import kotlinx.serialization.*
28
30
import kotlinx.serialization.builtins.serializer
29
31
import kotlinx.serialization.descriptors.*
30
- import kotlinx.serialization.encoding.Decoder
31
- import kotlinx.serialization.encoding.Encoder
32
+ import kotlinx.serialization.encoding.*
33
+ import love.forte.simbot.common.id.IntID.Companion.ID
34
+ import love.forte.simbot.common.id.LongID.Companion.ID
32
35
import love.forte.simbot.common.id.StringID.Companion.ID
36
+ import love.forte.simbot.common.id.UIntID.Companion.ID
37
+ import love.forte.simbot.common.id.ULongID.Companion.ID
33
38
import love.forte.simbot.common.id.UUID.Companion.UUID
34
39
import kotlin.concurrent.Volatile
35
40
import kotlin.experimental.and
36
41
import kotlin.experimental.or
37
42
import kotlin.js.JsName
43
+ import kotlin.jvm.JvmMultifileClass
38
44
import kotlin.jvm.JvmName
39
45
import kotlin.jvm.JvmOverloads
40
46
import kotlin.jvm.JvmStatic
@@ -55,6 +61,43 @@ import kotlin.random.Random
55
61
*
56
62
* 它们可以粗略的被归类为字符串类型( [UUID] 的字面值表现为字符串)和数字类型。
57
63
*
64
+ * ## 构造
65
+ *
66
+ * 在 Kotlin 中,直接使用各类型的伴生对象提供的扩展属性构建即可:
67
+ *
68
+ * ```Kotlin
69
+ * 100.ID
70
+ * 100L.ID
71
+ * 100u.ID
72
+ * "100".ID
73
+ * UUID.random()
74
+ * ```
75
+ *
76
+ * 在 Java 中,可以使用 `Identifies` 中提供的构造方法,它们通常被命名为 `of` 或以 `of` 为开头:
77
+ *
78
+ * ```Java
79
+ * Identifies.of(100);
80
+ * Identifies.of(100L);
81
+ * Identifies.of("100");
82
+ * Identifies.ofULong(100L);
83
+ * Identifies.ofULong("100");
84
+ * Identifies.uuid();
85
+ * ```
86
+ *
87
+ * 也可以使用具体类型的伴生对象所提供的静态API:
88
+ *
89
+ * ```Java
90
+ * IntID.valueOf(100);
91
+ * LongID.valueOf(100L);
92
+ * UIntID.valueOf(100);
93
+ * ULongID.valueOf(100L);
94
+ * StringID.valueOf("100");
95
+ * UUID.random();
96
+ * ```
97
+ *
98
+ * 这些伴生对象提供的静态API与 `Identifies` 中的内容相比缺少了一些辅助性的API,
99
+ * 例如使用字符串构建无符号ID `ULongID`。
100
+ *
58
101
* ## 序列化
59
102
*
60
103
* 所有**具体的**ID类型都是可序列化的,它们都会通过 Kotlinx serialization
@@ -506,6 +549,59 @@ public class UUID private constructor(
506
549
}
507
550
}
508
551
552
+ /* *
553
+ * 直接将 [UUID] 作为一个具有两个 [Long] 的结构体进行序列化的序列化器。
554
+ */
555
+ public object StructureSerializer : KSerializer<UUID> {
556
+ override val descriptor: SerialDescriptor = buildClassSerialDescriptor(" UUID" ) {
557
+ element(" mostSignificantBits" , Long .serializer().descriptor)
558
+ element(" leastSignificantBits" , Long .serializer().descriptor)
559
+ }
560
+
561
+ @OptIn(ExperimentalSerializationApi ::class )
562
+ override fun deserialize (decoder : Decoder ): UUID {
563
+ return decoder.decodeStructure(descriptor) {
564
+ var m = false
565
+ var l = false
566
+ var mostSignificantBits: Long = 0
567
+ var leastSignificantBits: Long = 0
568
+
569
+ while (true ) {
570
+ when (val index = decodeElementIndex(descriptor)) {
571
+ 0 -> {
572
+ m = true
573
+ mostSignificantBits = decodeLongElement(descriptor, index)
574
+ }
575
+
576
+ 1 -> {
577
+ l = true
578
+ leastSignificantBits = decodeLongElement(descriptor, index)
579
+ }
580
+
581
+ CompositeDecoder .DECODE_DONE -> break
582
+ else -> error(" Unexpected index: $index " )
583
+ }
584
+ }
585
+ if (! m || ! l) {
586
+ val properties = buildList {
587
+ if (! m) add(" mostSignificantBits" )
588
+ if (! l) add(" leastSignificantBits" )
589
+ }
590
+ throw MissingFieldException (properties, " love.forte.simbot.common.id.UUID" )
591
+ }
592
+
593
+ UUID (mostSignificantBits, leastSignificantBits)
594
+ }
595
+ }
596
+
597
+ override fun serialize (encoder : Encoder , value : UUID ) {
598
+ encoder.encodeStructure(descriptor) {
599
+ encodeLongElement(descriptor, 0 , value.mostSignificantBits)
600
+ encodeLongElement(descriptor, 1 , value.leastSignificantBits)
601
+ }
602
+ }
603
+ }
604
+
509
605
}
510
606
511
607
/* *
@@ -914,3 +1010,119 @@ private inline fun <reified T : ID> T.idExactEq(other: Any?, orElse: T.(T) -> Bo
914
1010
*/
915
1011
public inline val ID .literal: String
916
1012
get() = toString()
1013
+
1014
+ /* *
1015
+ * 尝试将 [this] 转化为 [Int]。
1016
+ * 如果为 [NumericalID] 则直接使用 [NumericalID.toInt],
1017
+ * 否则使用 [notNumerical] 转化。默认会尝试使用 [literal.toIntOrNull()][String.toIntOrNull]。
1018
+ */
1019
+ @JvmOverloads
1020
+ @JvmName(" toIntOrNull" )
1021
+ public inline fun ID.toIntOrNull (notNumerical : ID .() -> Int? = { literal.toIntOrNull() }): Int? =
1022
+ (this as ? NumericalID )?.toInt() ? : notNumerical()
1023
+
1024
+ /* *
1025
+ * 尝试将 [this] 转化为 [Int]。
1026
+ * 如果为 [NumericalID] 则直接使用 [NumericalID.toInt],
1027
+ * 否则使用 [notNumerical] 转化。默认会尝试使用 [literal.toInt()][String.toInt]。
1028
+ */
1029
+ @JvmOverloads
1030
+ @JvmName(" toInt" )
1031
+ public inline fun ID.toInt (notNumerical : ID .() -> Int = { literal.toInt() }): Int =
1032
+ (this as ? NumericalID )?.toInt() ? : notNumerical()
1033
+
1034
+ /* *
1035
+ * 尝试将 [this] 转化为 [Long]。
1036
+ * 如果为 [NumericalID] 则直接使用 [NumericalID.toLong],
1037
+ * 否则使用 [notNumerical] 转化。默认会尝试使用 [literal.toLongOrNull()][String.toLongOrNull]。
1038
+ */
1039
+ @JvmOverloads
1040
+ @JvmName(" toLongOrNull" )
1041
+ public inline fun ID.toLongOrNull (notNumerical : ID .() -> Long? = { literal.toLongOrNull() }): Long? =
1042
+ (this as ? NumericalID )?.toLong() ? : notNumerical()
1043
+
1044
+ /* *
1045
+ * 尝试将 [this] 转化为 [Long]。
1046
+ * 如果为 [NumericalID] 则直接使用 [NumericalID.toLong],
1047
+ * 否则使用 [notNumerical] 转化。默认会尝试使用 [literal.toLong()][String.toLong]。
1048
+ */
1049
+ @JvmOverloads
1050
+ @JvmName(" toLong" )
1051
+ public inline fun ID.toLong (notNumerical : ID .() -> Long = { literal.toLong() }): Long =
1052
+ (this as ? NumericalID )?.toLong() ? : notNumerical()
1053
+
1054
+ /* *
1055
+ * 尝试将 [this] 转化为 [UInt]。
1056
+ * 如果为 [NumericalID] 则直接使用 [NumericalID.toInt].[toUInt][Int.toUInt],
1057
+ * 否则使用 [notNumerical] 转化。默认会尝试使用 [literal.toUIntOrNull()][String.toIntOrNull]。
1058
+ */
1059
+ @JvmOverloads
1060
+ @JvmName(" toUIntOrNull" )
1061
+ public inline fun ID.toUIntOrNull (notNumerical : ID .() -> UInt? = { literal.toUIntOrNull() }): UInt? =
1062
+ (this as ? NumericalID )?.toInt()?.toUInt() ? : notNumerical()
1063
+
1064
+ /* *
1065
+ * 尝试将 [this] 转化为 [UInt]。
1066
+ * 如果为 [NumericalID] 则直接使用 [NumericalID.toInt].[toUInt][Int.toUInt],
1067
+ * 否则使用 [notNumerical] 转化。默认会尝试使用 [literal.toUInt()][String.toInt]。
1068
+ */
1069
+ @JvmOverloads
1070
+ @JvmName(" toUInt" )
1071
+ public inline fun ID.toUInt (notNumerical : ID .() -> UInt = { literal.toUInt() }): UInt =
1072
+ (this as ? NumericalID )?.toInt()?.toUInt() ? : notNumerical()
1073
+
1074
+ /* *
1075
+ * 尝试将 [this] 转化为 [ULong]。
1076
+ * 如果为 [NumericalID] 则直接使用 [NumericalID.toLong].[toULong][Long.toULong],
1077
+ * 否则使用 [notNumerical] 转化。默认会尝试使用 [literal.toULongOrNull()][String.toLongOrNull]。
1078
+ */
1079
+ @JvmOverloads
1080
+ @JvmName(" toULongOrNull" )
1081
+ public inline fun ID.toULongOrNull (notNumerical : ID .() -> ULong? = { literal.toULongOrNull() }): ULong? =
1082
+ (this as ? NumericalID )?.toLong()?.toULong() ? : notNumerical()
1083
+
1084
+ /* *
1085
+ * 尝试将 [this] 转化为 [ULong]。
1086
+ * 如果为 [NumericalID] 则直接使用 [NumericalID.toLong].[toULong][Long.toULong],
1087
+ * 否则使用 [notNumerical] 转化。默认会尝试使用 [literal.toULong()][String.toLong]。
1088
+ */
1089
+ @JvmOverloads
1090
+ @JvmName(" toULong" )
1091
+ public inline fun ID.toULong (notNumerical : ID .() -> ULong = { literal.toULong() }): ULong =
1092
+ (this as ? NumericalID )?.toLong()?.toULong() ? : notNumerical()
1093
+
1094
+ /* *
1095
+ * 尝试将 [this] 转为 [IntID] 类型。
1096
+ * 如果不是数字ID,则会使用 [notNumerical] 获取结果。默认使用 [String.toInt]。
1097
+ */
1098
+ @JvmOverloads
1099
+ @JvmName(" toIntID" )
1100
+ public inline fun ID.toIntID (notNumerical : ID .() -> IntID = { literal.toInt().ID }): IntID =
1101
+ this as ? IntID ? : (this as ? NumericalID )?.toInt()?.ID ? : notNumerical()
1102
+
1103
+ /* *
1104
+ * 尝试将 [this] 转为 [UIntID] 类型。
1105
+ * 如果不是数字ID,则会使用 [notNumerical] 获取结果。默认使用 [String.toUInt]。
1106
+ */
1107
+ @JvmOverloads
1108
+ @JvmName(" toUIntID" )
1109
+ public inline fun ID.toUIntID (notNumerical : ID .() -> UIntID = { literal.toUInt().ID }): UIntID =
1110
+ this as ? UIntID ? : (this as ? NumericalID )?.toUInt()?.ID ? : notNumerical()
1111
+
1112
+ /* *
1113
+ * 尝试将 [this] 转为 [LongID] 类型。
1114
+ * 如果不是数字ID,则会使用 [notNumerical] 获取结果。默认使用 [String.toLong]。
1115
+ */
1116
+ @JvmOverloads
1117
+ @JvmName(" toLongID" )
1118
+ public inline fun ID.toLongID (notNumerical : ID .() -> LongID = { literal.toLong().ID }): LongID =
1119
+ this as ? LongID ? : (this as ? NumericalID )?.toLong()?.ID ? : notNumerical()
1120
+
1121
+ /* *
1122
+ * 尝试将 [this] 转为 [ULongID] 类型。
1123
+ * 如果不是数字ID,则会使用 [notNumerical] 获取结果。默认使用 [String.toULong]。
1124
+ */
1125
+ @JvmOverloads
1126
+ @JvmName(" toULongID" )
1127
+ public inline fun ID.toULongID (notNumerical : ID .() -> ULongID = { literal.toULong().ID }): ULongID =
1128
+ this as ? ULongID ? : (this as ? NumericalID )?.toULong()?.ID ? : notNumerical()
0 commit comments