up
This commit is contained in:
@@ -210,8 +210,13 @@ type refList struct {
|
||||
byCode map[string]RefMeta // uppercased code → metadata
|
||||
codes []string // codes in input order (for stable unworked listing)
|
||||
withPattern []string // codes whose reference declares a regex (usually none)
|
||||
names []nameCode // (uppercased name → code) for MatchBy="description"
|
||||
}
|
||||
|
||||
// nameCode pairs a reference's uppercased description with its code, for
|
||||
// description-based matching (e.g. WAJA finding a prefecture NAME in the QTH).
|
||||
type nameCode struct{ name, code string }
|
||||
|
||||
// RefMeta is one reference's metadata for the engine: enough to enforce a
|
||||
// predefined list, per-reference DXCC scoping, a per-reference pattern, and to
|
||||
// label results.
|
||||
@@ -243,6 +248,9 @@ func NewRefList(metas []RefMeta) refList {
|
||||
m.Code = code
|
||||
if _, dup := rl.byCode[code]; !dup {
|
||||
rl.codes = append(rl.codes, code)
|
||||
if nm := strings.ToUpper(strings.TrimSpace(m.Name)); nm != "" {
|
||||
rl.names = append(rl.names, nameCode{name: nm, code: code})
|
||||
}
|
||||
}
|
||||
rl.byCode[code] = m
|
||||
}
|
||||
@@ -376,6 +384,15 @@ func Compute(defs []Def, qsos []qso.QSO, refMetas map[string][]RefMeta, nameOf N
|
||||
for _, b := range sortedBands(bandWorked) {
|
||||
r.Bands = append(r.Bands, BandCount{Band: b, Worked: bandWorked[b], Confirmed: bandConfirmed[b]})
|
||||
}
|
||||
// Never return nil slices: they marshal to JSON null, and the UI calls
|
||||
// .filter/.length on them (an award with nothing worked yet — e.g. a
|
||||
// freshly-created WWFF/WAJA — would otherwise white-screen the panel).
|
||||
if r.Refs == nil {
|
||||
r.Refs = []Ref{}
|
||||
}
|
||||
if r.Bands == nil {
|
||||
r.Bands = []BandCount{}
|
||||
}
|
||||
out[i] = r
|
||||
}
|
||||
return out
|
||||
@@ -428,12 +445,27 @@ func candidates(d *Def, re *regexp.Regexp, q *qso.QSO, rl refList, hasList bool)
|
||||
return nil
|
||||
}
|
||||
predefined := hasList && !d.Dynamic
|
||||
byDesc := predefined && strings.EqualFold(strings.TrimSpace(d.MatchBy), "description")
|
||||
|
||||
var found []string
|
||||
switch {
|
||||
case re != nil:
|
||||
// Award-level regex: capture group 1 (or whole match) for each hit.
|
||||
found = regexTokens(re, raw)
|
||||
case byDesc:
|
||||
// Match references by their DESCRIPTION/name appearing in the field
|
||||
// (e.g. WAJA finds the prefecture name inside the QTH). ExactMatch means
|
||||
// the field equals the name; otherwise the name is a substring of it.
|
||||
up := strings.ToUpper(raw)
|
||||
for _, nc := range rl.names {
|
||||
if d.ExactMatch {
|
||||
if up == nc.name {
|
||||
found = append(found, nc.code)
|
||||
}
|
||||
} else if strings.Contains(up, nc.name) {
|
||||
found = append(found, nc.code)
|
||||
}
|
||||
}
|
||||
case predefined && !d.ExactMatch:
|
||||
// "Search reference inside the field": look up each token of the field in
|
||||
// the list — O(tokens), not O(all references) — plus test the few
|
||||
|
||||
Reference in New Issue
Block a user