Add autofill app binding helpers
This commit is contained in:
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user