quintodrome/model/criteria/fields.go
Deluan 0fd9c6df2e refactor(smartplaylist): clarify FieldInfo naming in criteria package
Rename FieldInfo.Name to Alias (only meaningful for backward-compat
entries like albumtype→releasetype) and FieldInfo.alias to tagAlias
(tag names from mappings.yml that resolve to existing fields). Add a
Name() method that derives the canonical name from the map key,
eliminating 60+ redundant Name declarations where the value matched
the key. LookupField now populates the private name field automatically.

Signed-off-by: Deluan <deluan@navidrome.org>
2026-04-28 20:24:04 -04:00

163 lines
4.3 KiB
Go

package criteria
import "strings"
// FieldInfo contains semantic metadata about a criteria field.
type FieldInfo struct {
Alias string // If set, this field is a backward-compat alias for another canonical name
IsTag bool
IsRole bool
Numeric bool
tagAlias string // If set, a tag name from mappings.yml that resolves to this field
name string // Canonical name, populated by LookupField from the map key
}
// Name returns the canonical field name (the map key used to register this field).
func (f FieldInfo) Name() string {
return f.name
}
var fieldMap = map[string]FieldInfo{
"title": {},
"album": {},
"hascoverart": {},
"tracknumber": {},
"discnumber": {},
"year": {},
"date": {tagAlias: "recordingdate"},
"originalyear": {},
"originaldate": {},
"releaseyear": {},
"releasedate": {},
"size": {},
"compilation": {},
"missing": {},
"explicitstatus": {},
"dateadded": {},
"datemodified": {},
"discsubtitle": {},
"comment": {},
"lyrics": {},
"sorttitle": {},
"sortalbum": {},
"sortartist": {},
"sortalbumartist": {},
"albumcomment": {},
"catalognumber": {},
"filepath": {},
"filetype": {},
"codec": {},
"duration": {},
"bitrate": {},
"bitdepth": {},
"samplerate": {},
"bpm": {},
"channels": {},
"loved": {},
"dateloved": {},
"lastplayed": {},
"daterated": {},
"playcount": {},
"rating": {},
"averagerating": {Numeric: true},
"albumrating": {},
"albumloved": {},
"albumplaycount": {},
"albumlastplayed": {},
"albumdateloved": {},
"albumdaterated": {},
"artistrating": {},
"artistloved": {},
"artistplaycount": {},
"artistlastplayed": {},
"artistdateloved": {},
"artistdaterated": {},
"mbz_album_id": {},
"mbz_album_artist_id": {},
"mbz_artist_id": {},
"mbz_recording_id": {},
"mbz_release_track_id": {},
"mbz_release_group_id": {},
"rgalbumgain": {Numeric: true},
"rgalbumpeak": {Numeric: true},
"rgtrackgain": {Numeric: true},
"rgtrackpeak": {Numeric: true},
"library_id": {Numeric: true},
// Backward compatibility: albumtype is an alias for the releasetype tag.
"albumtype": {Alias: "releasetype", IsTag: true},
"random": {},
"value": {},
}
// AllFieldNames returns the names of all registered criteria fields.
func AllFieldNames() []string {
names := make([]string, 0, len(fieldMap))
for name := range fieldMap {
names = append(names, name)
}
return names
}
// LookupField returns semantic metadata for a criteria field name.
func LookupField(name string) (FieldInfo, bool) {
key := strings.ToLower(name)
f, ok := fieldMap[key]
if ok {
if f.Alias != "" {
f.name = f.Alias
} else {
f.name = key
}
}
return f, ok
}
// AddRoles adds roles to the field map. This is used to add all artist roles to the field map, so they can be used in
// smart playlists.
func AddRoles(roles []string) {
for _, role := range roles {
name := strings.ToLower(role)
if _, ok := fieldMap[name]; ok {
continue
}
fieldMap[name] = FieldInfo{IsRole: true}
}
}
// AddTagNames adds tag names to the field map. This is used to add all tags mapped in the `mappings.yml`
// configuration file.
func AddTagNames(tagNames []string) {
for _, tagName := range tagNames {
name := strings.ToLower(tagName)
if _, ok := fieldMap[name]; ok {
continue
}
for key, fm := range fieldMap {
if fm.tagAlias == name {
fm.Alias = key
fm.tagAlias = ""
fieldMap[name] = fm
break
}
}
if _, ok := fieldMap[name]; !ok {
fieldMap[name] = FieldInfo{IsTag: true}
}
}
}
// AddNumericTags adds tags that should be treated as numbers.
func AddNumericTags(tagNames []string) {
for _, tagName := range tagNames {
name := strings.ToLower(tagName)
if fm, ok := fieldMap[name]; ok {
fm.Numeric = true
fieldMap[name] = fm
} else {
fieldMap[name] = FieldInfo{IsTag: true, Numeric: true}
}
}
}