refactor(artwork): tidy extractDiscNumber after glob-wildcard support

- Name the '*?[' charset as globMetaChars, used by both extractDiscNumber
  and fromExternalFile so the two call sites can't drift.
- Trim the extractDiscNumber doc comment: keep the non-obvious caller
  contract, drop the algorithm narration.
- Replace the byte-slice digit accumulator with a direct filename slice
  fed to strconv.Atoi.
- Rename the four new non-'*' wildcard Entry descriptions so they read
  like the existing extractDiscNumber table ('pattern, target → expected')
  instead of the ambiguous 'disc 1' shorthand.
This commit is contained in:
Deluan 2026-04-11 20:37:22 -04:00
commit 3fd106d675
2 changed files with 16 additions and 18 deletions

View file

@ -168,16 +168,17 @@ func (d *discArtworkReader) fromDiscSubtitle(ctx context.Context, subtitle strin
}
}
// globMetaChars lists every metacharacter understood by filepath.Match.
const globMetaChars = "*?["
// extractDiscNumber parses the disc number from a filename matched by a
// filepath.Match-style glob pattern. It takes the literal prefix of the
// pattern (everything before the first '*', '?', or '[' metacharacter),
// strips it from the filename, and reads the leading digits that follow.
// filepath.Match-style glob pattern.
//
// Both pattern and filename must already be lowercased by the caller, which
// is also expected to have verified that filepath.Match(pattern, filename)
// is true before calling this function.
func extractDiscNumber(pattern, filename string) (int, bool) {
metaIdx := strings.IndexAny(pattern, "*?[")
metaIdx := strings.IndexAny(pattern, globMetaChars)
if metaIdx < 0 {
return 0, false
}
@ -186,18 +187,15 @@ func extractDiscNumber(pattern, filename string) (int, bool) {
return 0, false
}
var digits []byte
for i := len(prefix); i < len(filename); i++ {
c := filename[i]
if c < '0' || c > '9' {
break
}
digits = append(digits, c)
start := len(prefix)
end := start
for end < len(filename) && filename[end] >= '0' && filename[end] <= '9' {
end++
}
if len(digits) == 0 {
if end == start {
return 0, false
}
num, err := strconv.Atoi(string(digits))
num, err := strconv.Atoi(filename[start:end])
if err != nil {
return 0, false
}
@ -208,7 +206,7 @@ func extractDiscNumber(pattern, filename string) (int, bool) {
// pattern. A numbered filename whose number equals the target disc wins over
// any unnumbered candidate; callers must pass a lowercase pattern.
func (d *discArtworkReader) fromExternalFile(ctx context.Context, pattern string) sourceFunc {
isLiteral := !strings.ContainsAny(pattern, "*?[")
isLiteral := !strings.ContainsAny(pattern, globMetaChars)
return func() (io.ReadCloser, string, error) {
var fallback string
for _, file := range d.imgFiles {

View file

@ -226,10 +226,10 @@ var _ = Describe("Disc Artwork Reader", func() {
r.Close()
Expect(path).To(Equal(files[expectedIdx]))
},
Entry("'?' wildcard, disc 1", "disc?.jpg", 1, 0),
Entry("'?' wildcard, disc 2", "disc?.jpg", 2, 1),
Entry("character class, disc 1", "disc[0-9].jpg", 1, 0),
Entry("character class, disc 2", "disc[0-9].jpg", 2, 1),
Entry("disc?.jpg, target disc 1 → disc1.jpg", "disc?.jpg", 1, 0),
Entry("disc?.jpg, target disc 2 → disc2.jpg", "disc?.jpg", 2, 1),
Entry("disc[0-9].jpg, target disc 1 → disc1.jpg", "disc[0-9].jpg", 1, 0),
Entry("disc[0-9].jpg, target disc 2 → disc2.jpg", "disc[0-9].jpg", 2, 1),
)
It("matches file without number in multi-folder album by folder", func() {