88 lines
2.3 KiB
Go
88 lines
2.3 KiB
Go
package autofillcache
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"slices"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type BindingsFile struct {
|
|
UpdatedAt string `json:"updatedAt"`
|
|
Apps map[string]string `json:"apps,omitempty"`
|
|
}
|
|
|
|
func ReadBindings(path string) (BindingsFile, error) {
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
return BindingsFile{}, nil
|
|
}
|
|
return BindingsFile{}, err
|
|
}
|
|
var bindings BindingsFile
|
|
if err := json.Unmarshal(data, &bindings); err != nil {
|
|
return BindingsFile{}, err
|
|
}
|
|
if bindings.Apps == nil {
|
|
bindings.Apps = make(map[string]string)
|
|
}
|
|
return bindings, nil
|
|
}
|
|
|
|
func RememberBinding(path, rawTarget, entryID string, now time.Time) error {
|
|
bindings, err := ReadBindings(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if bindings.Apps == nil {
|
|
bindings.Apps = make(map[string]string)
|
|
}
|
|
target := strings.TrimSpace(rawTarget)
|
|
id := strings.TrimSpace(entryID)
|
|
if target == "" || id == "" {
|
|
return nil
|
|
}
|
|
bindings.Apps[target] = id
|
|
bindings.UpdatedAt = now.UTC().Format(time.RFC3339)
|
|
data, err := json.MarshalIndent(bindings, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
return err
|
|
}
|
|
return os.WriteFile(path, data, 0o600)
|
|
}
|
|
|
|
func ResolveWithBindings(cache File, bindings BindingsFile, rawTarget string) MatchResult {
|
|
target := strings.TrimSpace(rawTarget)
|
|
if entryID := strings.TrimSpace(bindings.Apps[target]); entryID != "" {
|
|
for _, entry := range cache.Entries {
|
|
if entry.ID == entryID {
|
|
return MatchResult{Status: MatchStatusFound, Entry: entry}
|
|
}
|
|
}
|
|
}
|
|
return Resolve(cache, rawTarget)
|
|
}
|
|
|
|
func ChooserCandidates(cache File, rawTarget string) []Entry {
|
|
if result := Resolve(cache, rawTarget); result.Status == MatchStatusFound {
|
|
return []Entry{result.Entry}
|
|
}
|
|
candidates := append([]Entry(nil), cache.Entries...)
|
|
slices.SortFunc(candidates, func(left, right Entry) int {
|
|
if cmp := strings.Compare(strings.ToLower(strings.TrimSpace(left.Title)), strings.ToLower(strings.TrimSpace(right.Title))); cmp != 0 {
|
|
return cmp
|
|
}
|
|
if cmp := strings.Compare(strings.ToLower(strings.Join(left.Path, "/")), strings.ToLower(strings.Join(right.Path, "/"))); cmp != 0 {
|
|
return cmp
|
|
}
|
|
return strings.Compare(left.ID, right.ID)
|
|
})
|
|
return candidates
|
|
}
|