diff --git a/musikr/src/main/java/org/oxycblt/musikr/pipeline/FlowUtil.kt b/musikr/src/main/java/org/oxycblt/musikr/pipeline/FlowUtil.kt index 94d93c4c2..fd0a3cce6 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/pipeline/FlowUtil.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/pipeline/FlowUtil.kt @@ -31,7 +31,7 @@ internal sealed interface Divert { data class Right(val value: R) : Divert } -class DivertedFlow(val manager: Flow, val left: Flow, val right: Flow) +internal class DivertedFlow(val manager: Flow, val left: Flow, val right: Flow) internal inline fun Flow.divert( crossinline predicate: (T) -> Divert diff --git a/musikr/src/main/java/org/oxycblt/musikr/tag/Name.kt b/musikr/src/main/java/org/oxycblt/musikr/tag/Name.kt index ee852d3da..9197482d3 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/tag/Name.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/tag/Name.kt @@ -18,7 +18,7 @@ package org.oxycblt.musikr.tag -import org.oxycblt.musikr.tag.interpret.Token +import java.text.CollationKey /** * The name of a music item. @@ -66,6 +66,36 @@ sealed interface Name : Comparable { } } +/** An individual part of a name string that can be compared intelligently. */ +data class Token(internal val collationKey: CollationKey, internal val type: Type) : Comparable { + val value: String get() = collationKey.sourceString + + override fun compareTo(other: Token): Int { + // Numeric tokens should always be lower than lexicographic tokens. + val modeComp = type.compareTo(other.type) + if (modeComp != 0) { + return modeComp + } + + // Numeric strings must be ordered by magnitude, thus immediately short-circuit + // the comparison if the lengths do not match. + if (type == Type.NUMERIC && + collationKey.sourceString.length != other.collationKey.sourceString.length) { + return collationKey.sourceString.length - other.collationKey.sourceString.length + } + + return collationKey.compareTo(other.collationKey) + } + + /** Denotes the type of comparison to be performed with this token. */ + enum class Type { + /** Compare as a digit string, like "65". */ + NUMERIC, + /** Compare as a standard alphanumeric string, like "65daysofstatic" */ + LEXICOGRAPHIC + } +} + enum class Placeholder { ALBUM, ARTIST, diff --git a/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Naming.kt b/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Naming.kt index 79300de45..d1d8d0b63 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Naming.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Naming.kt @@ -22,6 +22,7 @@ import java.text.CollationKey import java.text.Collator import org.oxycblt.musikr.tag.Name import org.oxycblt.musikr.tag.Placeholder +import org.oxycblt.musikr.tag.Token abstract class Naming { fun name(raw: String?, sort: String?, placeholder: Placeholder): Name = diff --git a/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Token.kt b/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Token.kt deleted file mode 100644 index c09ba3521..000000000 --- a/musikr/src/main/java/org/oxycblt/musikr/tag/interpret/Token.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2024 Auxio Project - * Token.kt is part of Auxio. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.oxycblt.musikr.tag.interpret - -import java.text.CollationKey - -/** An individual part of a name string that can be compared intelligently. */ -data class Token(internal val collationKey: CollationKey, internal val type: Type) : Comparable { - val value: String get() = collationKey.sourceString - - override fun compareTo(other: Token): Int { - // Numeric tokens should always be lower than lexicographic tokens. - val modeComp = type.compareTo(other.type) - if (modeComp != 0) { - return modeComp - } - - // Numeric strings must be ordered by magnitude, thus immediately short-circuit - // the comparison if the lengths do not match. - if (type == Type.NUMERIC && - collationKey.sourceString.length != other.collationKey.sourceString.length) { - return collationKey.sourceString.length - other.collationKey.sourceString.length - } - - return collationKey.compareTo(other.collationKey) - } - - /** Denotes the type of comparison to be performed with this token. */ - enum class Type { - /** Compare as a digit string, like "65". */ - NUMERIC, - /** Compare as a standard alphanumeric string, like "65daysofstatic" */ - LEXICOGRAPHIC - } -} diff --git a/musikr/src/main/java/org/oxycblt/musikr/tag/parse/TagParser.kt b/musikr/src/main/java/org/oxycblt/musikr/tag/parse/TagParser.kt index 9bfce156d..fcf3e48b8 100644 --- a/musikr/src/main/java/org/oxycblt/musikr/tag/parse/TagParser.kt +++ b/musikr/src/main/java/org/oxycblt/musikr/tag/parse/TagParser.kt @@ -20,6 +20,7 @@ package org.oxycblt.musikr.tag.parse import org.oxycblt.musikr.fs.DeviceFile import org.oxycblt.musikr.metadata.Metadata +import org.oxycblt.musikr.util.unlikelyToBeNull internal interface TagParser { fun parse(file: DeviceFile, metadata: Metadata): ParsedTags @@ -29,8 +30,6 @@ internal interface TagParser { } } -class MissingTagError(what: String) : Error("missing tag: $what") - private data object TagParserImpl : TagParser { override fun parse(file: DeviceFile, metadata: Metadata): ParsedTags { return ParsedTags( @@ -38,7 +37,7 @@ private data object TagParserImpl : TagParser { replayGainTrackAdjustment = metadata.replayGainTrackAdjustment(), replayGainAlbumAdjustment = metadata.replayGainAlbumAdjustment(), musicBrainzId = metadata.musicBrainzId(), - name = metadata.name() ?: file.path.name ?: throw MissingTagError("name"), + name = metadata.name() ?: unlikelyToBeNull(file.path.name), sortName = metadata.sortName(), track = metadata.track(), disc = metadata.disc(), diff --git a/musikr/src/test/java/org/oxycblt/musikr/tag/NameTest.kt b/musikr/src/test/java/org/oxycblt/musikr/tag/NameTest.kt index 285b12fee..a44f79708 100644 --- a/musikr/src/test/java/org/oxycblt/musikr/tag/NameTest.kt +++ b/musikr/src/test/java/org/oxycblt/musikr/tag/NameTest.kt @@ -22,7 +22,6 @@ import org.junit.Assert.assertEquals import org.junit.Assert.assertNotEquals import org.junit.Test import org.oxycblt.musikr.tag.interpret.Naming -import org.oxycblt.musikr.tag.interpret.Token class NameTest { @Test