diff options
| author | Sho Sakuma <me@m1sk9.dev> | 2026-08-02 19:10:46 +0900 |
|---|---|---|
| committer | Sho Sakuma <me@m1sk9.dev> | 2026-08-02 19:10:56 +0900 |
| commit | bc0d7d522e169f3eeb8d5b632ee673392060694b (patch) | |
| tree | 3cd616cc96904964a20bab267dc5112ba4719d6d /engine | |
| parent | 1dd2787059331db57049cb1dac8a38ceea859992 (diff) | |
| download | LunaticChat-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')
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) - } - } } |
