Add autofill app binding helpers

This commit is contained in:
Joe Julian
2026-04-13 17:30:33 -07:00
parent 361d6dbe03
commit c302c29d4f
+87
View File
@@ -0,0 +1,87 @@
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
}