summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
authorSho Sakuma <me@m1sk9.dev>2026-08-02 19:10:46 +0900
committerSho Sakuma <me@m1sk9.dev>2026-08-02 19:10:56 +0900
commitbc0d7d522e169f3eeb8d5b632ee673392060694b (patch)
tree3cd616cc96904964a20bab267dc5112ba4719d6d /engine
parent1dd2787059331db57049cb1dac8a38ceea859992 (diff)
downloadLunaticChat-bc0d7d522e169f3eeb8d5b632ee673392060694b.tar.gz
LunaticChat-bc0d7d522e169f3eeb8d5b632ee673392060694b.tar.bz2
LunaticChat-bc0d7d522e169f3eeb8d5b632ee673392060694b.zip
refactor: remove code that no production path reaches
These were all scaffolding that drifted out of use, and each one costs a reader time before they discover it does nothing: - UUIDASStringSerializer duplicated UUIDSerializer byte for byte; the differing descriptor name never reaches the JSON/YAML wire format, so the choice between them was a coin flip for contributors. - Velocity's BuildInfo was never referenced (the plugin reads its version from PluginContainer) and read a "commit" property the build never wrote, so it would have reported "unknown" had anyone called it. - KanaConverter.TrieNode.Leaf is never constructed: buildTrie starts from a Branch and insert only ever returns Branch. Six branches guarded against a state the type system allowed but the code could not produce. With those gone, isValidRomaji and toHiragana were visibly the same trie walk, so they now share one longestMatch. - @Deprecated command handling had no annotated command to act on. - The settings backup restore looked for *.backup.* files that nothing in the repository writes, so it always fell through to empty settings. Also drops CommandContext.replyWithEvent/replyPlain, PluginCoroutineScope's unused plugin parameter, GitHubRelease fields no caller reads, and four language keys with no lookup site. Co-Authored-By: Claude <noreply@anthropic.com>
Diffstat (limited to 'engine')
-rw-r--r--engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/converter/KanaConverter.kt123
-rw-r--r--engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/PlayerSettingsData.kt6
-rw-r--r--engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDASStringSerializer.kt27
-rw-r--r--engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializer.kt2
-rw-r--r--engine/src/test/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializerTest.kt44
5 files changed, 40 insertions, 162 deletions
diff --git a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/converter/KanaConverter.kt b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/converter/KanaConverter.kt
index 24e3560..bdbdf69 100644
--- a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/converter/KanaConverter.kt
+++ b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/converter/KanaConverter.kt
@@ -4,16 +4,10 @@ package dev.m1sk9.lunaticChat.engine.converter
* Converts romanji text to hiragana using Trie data structure.
*/
object KanaConverter {
- sealed class TrieNode {
- data class Leaf(
- val value: String,
- ) : TrieNode()
-
- data class Branch(
- val children: Map<Char, TrieNode>,
- val value: String? = null,
- ) : TrieNode()
- }
+ private class TrieNode(
+ val children: Map<Char, TrieNode>,
+ val value: String? = null,
+ )
private val romanjiTrie: TrieNode = buildTrie()
@@ -216,7 +210,7 @@ object KanaConverter {
"n" to "ん",
)
- return insertAll(TrieNode.Branch(emptyMap()), mappings)
+ return insertAll(TrieNode(emptyMap()), mappings)
}
private fun insertAll(
@@ -235,22 +229,33 @@ object KanaConverter {
key: String,
value: String,
): TrieNode {
- if (key.isEmpty()) {
- return when (node) {
- is TrieNode.Branch -> TrieNode.Branch(node.children, value)
- is TrieNode.Leaf -> TrieNode.Leaf(value)
- }
- }
+ if (key.isEmpty()) return TrieNode(node.children, value)
- return when (node) {
- is TrieNode.Branch -> {
- val char = key[0]
- val child = node.children[char] ?: TrieNode.Branch(emptyMap())
- val newChild = insert(child, key.substring(1), value)
- TrieNode.Branch(node.children + (char to newChild), node.value)
- }
- is TrieNode.Leaf -> node
+ val char = key[0]
+ val child = node.children[char] ?: TrieNode(emptyMap())
+ return TrieNode(node.children + (char to insert(child, key.substring(1), value)), node.value)
+ }
+
+ /**
+ * Walks the trie from [start] and returns the longest mapping that matches, paired with the
+ * number of characters it consumed, or null when no prefix of the input maps to kana.
+ */
+ private fun longestMatch(
+ input: String,
+ start: Int,
+ ): Pair<String, Int>? {
+ var node = romanjiTrie
+ var match: Pair<String, Int>? = null
+ var i = start
+
+ while (true) {
+ node.value?.let { match = it to (i - start) }
+ if (i >= input.length) break
+ node = node.children[input[i]] ?: break
+ i++
}
+
+ return match
}
/**
@@ -282,39 +287,8 @@ object KanaConverter {
}
}
- // Try to find the longest match in the trie
- var node: TrieNode = romanjiTrie
- var matchLength = 0
- var j = i
-
- while (j < lowerInput.length && lowerInput[j] in 'a'..'z') {
- node =
- when (node) {
- is TrieNode.Branch -> {
- if (node.value != null) {
- matchLength = j - i
- }
- node.children[lowerInput[j]] ?: break
- }
- is TrieNode.Leaf -> {
- matchLength = j - i
- break
- }
- }
- j++
- }
-
- // Check for terminal match
- if (node is TrieNode.Leaf) {
- matchLength = j - i
- } else if (node is TrieNode.Branch && node.value != null) {
- matchLength = j - i
- }
-
// If no match found, this character cannot be converted - not valid romaji
- if (matchLength == 0) {
- return false
- }
+ val (_, matchLength) = longestMatch(lowerInput, i) ?: return false
i += matchLength
}
@@ -344,37 +318,10 @@ object KanaConverter {
}
}
- var node: TrieNode = romanjiTrie
- var lastMatch: Pair<String, Int>? = null
- var j = i
-
- while (j < lowerInput.length) {
- node =
- when (node) {
- is TrieNode.Branch -> {
- if (node.value != null) {
- lastMatch = node.value to (j - i)
- }
-
- node.children[lowerInput[j]] ?: break
- }
- is TrieNode.Leaf -> {
- lastMatch = node.value to (j - i)
- break
- }
- }
- j++
- }
-
- if (node is TrieNode.Leaf) {
- lastMatch = node.value to (j - i)
- } else if (node is TrieNode.Branch && node.value != null) {
- lastMatch = node.value to (j - i)
- }
-
- if (lastMatch != null) {
- result.append(lastMatch.first)
- i += lastMatch.second
+ val match = longestMatch(lowerInput, i)
+ if (match != null) {
+ result.append(match.first)
+ i += match.second
} else {
result.append(lowerInput[i])
i++
diff --git a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/PlayerSettingsData.kt b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/PlayerSettingsData.kt
index 0e3cd24..91c37b8 100644
--- a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/PlayerSettingsData.kt
+++ b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/PlayerSettingsData.kt
@@ -30,17 +30,17 @@ import java.util.UUID
data class PlayerSettingsData(
val version: Int = 1,
val japaneseConversion: Map<
- @Serializable(with = UUIDASStringSerializer::class)
+ @Serializable(with = UUIDSerializer::class)
UUID,
Boolean,
> = emptyMap(),
val directMessageNotification: Map<
- @Serializable(with = UUIDASStringSerializer::class)
+ @Serializable(with = UUIDSerializer::class)
UUID,
Boolean,
> = emptyMap(),
val channelMessageNotification: Map<
- @Serializable(with = UUIDASStringSerializer::class)
+ @Serializable(with = UUIDSerializer::class)
UUID,
Boolean,
> = emptyMap(),
diff --git a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDASStringSerializer.kt b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDASStringSerializer.kt
deleted file mode 100644
index 7e6b331..0000000
--- a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDASStringSerializer.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package dev.m1sk9.lunaticChat.engine.settings
-
-import kotlinx.serialization.KSerializer
-import kotlinx.serialization.descriptors.PrimitiveKind
-import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
-import kotlinx.serialization.descriptors.SerialDescriptor
-import kotlinx.serialization.encoding.Decoder
-import kotlinx.serialization.encoding.Encoder
-import java.util.UUID
-
-/**
- * Serializer for UUID that converts to/from String format for YAML compatibility.
- * Used in PlayerSettingsData for serializing UUID keys in maps.
- */
-object UUIDASStringSerializer : KSerializer<UUID> {
- override val descriptor: SerialDescriptor =
- PrimitiveSerialDescriptor("UUIDAsString", PrimitiveKind.STRING)
-
- override fun serialize(
- encoder: Encoder,
- value: UUID,
- ) {
- encoder.encodeString(value.toString())
- }
-
- override fun deserialize(decoder: Decoder): UUID = UUID.fromString(decoder.decodeString())
-}
diff --git a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializer.kt b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializer.kt
index e03c1c1..dd01616 100644
--- a/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializer.kt
+++ b/engine/src/main/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializer.kt
@@ -11,6 +11,8 @@ import java.util.UUID
/**
* Custom serializer for UUID with kotlinx.serialization.
* kotlinx.serialization doesn't support UUID by default, so we need a custom serializer.
+ *
+ * Used for both UUID properties and UUID map keys (JSON and YAML alike).
*/
object UUIDSerializer : KSerializer<UUID> {
override val descriptor: SerialDescriptor =
diff --git a/engine/src/test/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializerTest.kt b/engine/src/test/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializerTest.kt
index 599a372..58d9c32 100644
--- a/engine/src/test/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializerTest.kt
+++ b/engine/src/test/kotlin/dev/m1sk9/lunaticChat/engine/settings/UUIDSerializerTest.kt
@@ -16,12 +16,6 @@ class UUIDSerializerTest {
val uuid: UUID,
)
- @Serializable
- private data class UUIDAsStringHolder(
- @Serializable(with = UUIDASStringSerializer::class)
- val uuid: UUID,
- )
-
@Test
fun `UUIDSerializer should serialize UUID to string`() {
val uuid = UUID.fromString("12345678-1234-1234-1234-123456789abc")
@@ -52,35 +46,6 @@ class UUIDSerializerTest {
}
@Test
- fun `UUIDASStringSerializer should serialize UUID to string`() {
- val uuid = UUID.fromString("abcdef01-2345-6789-abcd-ef0123456789")
- val holder = UUIDAsStringHolder(uuid)
-
- val jsonString = json.encodeToString(UUIDAsStringHolder.serializer(), holder)
-
- assert(jsonString.contains("abcdef01-2345-6789-abcd-ef0123456789"))
- }
-
- @Test
- fun `UUIDASStringSerializer should deserialize string to UUID`() {
- val jsonString = """{"uuid":"abcdef01-2345-6789-abcd-ef0123456789"}"""
- val holder = json.decodeFromString(UUIDAsStringHolder.serializer(), jsonString)
-
- assertEquals(UUID.fromString("abcdef01-2345-6789-abcd-ef0123456789"), holder.uuid)
- }
-
- @Test
- fun `UUIDASStringSerializer round-trip should preserve UUID`() {
- val originalUuid = UUID.randomUUID()
- val holder = UUIDAsStringHolder(originalUuid)
-
- val jsonString = json.encodeToString(UUIDAsStringHolder.serializer(), holder)
- val decoded = json.decodeFromString(UUIDAsStringHolder.serializer(), jsonString)
-
- assertEquals(originalUuid, decoded.uuid)
- }
-
- @Test
fun `UUIDSerializer should fail on invalid UUID string`() {
val jsonString = """{"uuid":"not-a-valid-uuid"}"""
@@ -88,13 +53,4 @@ class UUIDSerializerTest {
json.decodeFromString(UUIDHolder.serializer(), jsonString)
}
}
-
- @Test
- fun `UUIDASStringSerializer should fail on invalid UUID string`() {
- val jsonString = """{"uuid":"not-a-valid-uuid"}"""
-
- assertFailsWith<Exception> {
- json.decodeFromString(UUIDAsStringHolder.serializer(), jsonString)
- }
- }
}